C++11 中的“return ”语句是啥意思?
Posted
技术标签:
【中文标题】C++11 中的“return ”语句是啥意思?【英文标题】:What does "return " statement mean in C++11?C++11 中的“return ”语句是什么意思? 【发布时间】:2017-01-22 01:27:19 【问题描述】:声明是什么
return ;
在 C++11 中指明,以及何时使用它来代替(说)
return NULL;
或
return nullptr;
【问题讨论】:
它返回函数返回类型的默认构造实例。 还是简单的return;
没有价值?
不,正如讨论所揭示的那样,如果你的函数应该返回一些东西(即不是 void 返回类型)并且你只写return;
,这是一个编译时错误,另一方面return;
如果您有返回类型,则有效。
@Pedia 并非总是如此,某些对象将需要参数来构造
【参考方案1】:
这可能令人困惑:
int foo()
return ; // honestly, just return 0 - it's clearer
这可能不是:
SomeObjectWithADefaultConstructor foo()
return ;
// equivalent to return SomeObjectWithADefaultConstructor ;
【讨论】:
所以,如果返回类型没有默认构造函数,是编译时错误,对吗? 如果返回类型是一个没有非显式默认构造函数且不是聚合的类,则编译错误。 如果该类型有initializer_list
构造函数,如果没有可用的默认构造函数,那不就用了吗?
“可能令人困惑”?这就是为什么一些不知名的灵魂会提到“C++那个臃肿的淫秽”吗?这提供的任何击键节省是否可以证明它提供的缺乏清晰度的可能性?这是一个真诚的问题。请用实际例子说服我。
return
不等于 return SomeObjectWithADefaultConstructor;
【参考方案2】:
这是方法返回类型的新实例的一种简写。
【讨论】:
【参考方案3】:return ;
表示 是返回值 的初始值设定项。返回值使用空列表进行列表初始化。
以下是关于返回值的一些背景,基于 C++ 标准中的 [stmt.return]:
对于按值返回的函数(即返回类型不是引用而不是void
),有一个称为返回值的临时对象。这个对象是由return
语句创建的,它的初始化器取决于return 语句中的内容。
返回值一直存在到调用函数的代码中的完整表达式结束为止;如果它有类类型,那么它的析构函数将运行,除非它的生命周期被调用者直接绑定到它的引用而延长。
可以通过两种不同的方式初始化返回值:
return some_expression;
- 返回值为copy-initialized 来自some_expression
return possibly_empty_list ;
- 返回值为
list-initialized 来自列表。
假设T
是函数的返回类型,那么注意return T;
与return
不同:前者会创建一个临时的T
,然后返回值从那个临时复制初始化。
如果T
没有可访问的复制/移动构造函数,这将无法编译,但即使这些构造函数不存在,return ;
也会成功。因此,return T;
可能会显示复制构造函数等的副作用,尽管这是复制省略上下文,因此可能不会。
以下是 C++14 (N4140 [dcl.init.list]/3) 中 list-initialization 的简要回顾,其中初始化程序是一个空列表:
如果T
是一个聚合,则每个成员都从其 brace-or-equal-initializer 初始化(如果有),否则就像
一样(因此递归地应用这些步骤)。
如果T
是具有用户提供的默认构造函数的类类型,则调用该构造函数。
如果T
是具有隐式定义或= default
ed 默认构造函数的类类型,则对象为zero-initialized,然后调用默认构造函数。
如果T
是std::initializer_list
,则返回值为空的此类列表。
否则(即T
是非类类型——返回类型不能是数组),返回值初始化为零。
【讨论】:
聚合初始化首先出现,它递归地用
初始化每个成员,这可能是也可能不是value-init。
@T.C.对,我通过 cppreference 去了,但忽略了“直到 C++14”【参考方案4】:
return ;
表示“返回函数返回类型的对象,该对象使用空的list-initializer 初始化”。确切的行为取决于返回对象的类型。
来自cppreference.com(因为OP被标记为C++11,所以我排除了C++14和C++17中的规则;详情参考链接):
如果花括号初始化列表为空且 T 是具有默认构造函数的类类型,则执行值初始化。 否则,如果 T 是聚合类型,则执行聚合初始化。 否则,如果 T 是 std::initializer_list 的特化,则根据上下文,从花括号初始化列表中直接初始化或复制初始化 T 对象。否则,将分两个阶段考虑 T 的构造函数:
如果前一阶段未产生匹配,则 T 的所有构造函数都参与重载决议,以针对由括号初始化列表的元素组成的参数集,并限制只允许非缩小转换.如果此阶段生成一个显式构造函数作为复制列表初始化的最佳匹配,则编译失败(注意,在简单的复制初始化中,根本不考虑显式构造函数)。否则(如果 T 不是类类型),如果括号初始化列表只有一个元素并且 T 不是引用类型或者是与类型兼容的引用类型元素, T 是直接初始化(在直接列表初始化中)或复制初始化(在复制列表初始化中),但不允许缩小转换。
否则,如果 T 是与元素类型不兼容的引用类型。 (如果引用是非常量左值引用,则失败) 否则,如果花括号初始化列表没有元素,则 T 是值初始化的。
在 C++11 之前,对于返回 std::string
的函数,您应该这样写:
std::string get_string()
return std::string();
使用C++11中的大括号语法,不需要重复类型:
std::string get_string()
return ; // an empty string is returned
函数返回指针类型时,应使用return NULL
和return nullptr
:
any_type* get_pointer()
return nullptr;
但是,NULL
自 C++11 起已弃用,因为它只是整数值 (0) 的别名,而 nullptr
是真正的指针类型:
int get_int()
return NULL; // will compile, NULL is an integer
int get_int()
return nullptr; // error: nullptr is not an integer
【讨论】:
以上是关于C++11 中的“return ”语句是啥意思?的主要内容,如果未能解决你的问题,请参考以下文章