[英]What does `class template Example<int>;` statement mean with C++11?
[英]What does “return {}” statement mean in C++11?
这句话是什么?
return {};
在C ++ 11中指出,何时使用它而不是(比如说)
return NULL;
要么
return nullptr;
return {};
表示“返回使用空list-initializer初始化的函数返回类型的对象”。 确切的行为取决于返回的对象的类型。
来自cppreference.com (因为OP标记为C ++ 11,我排除了C ++ 14和C ++ 17中的规则;请参阅该链接以获取更多详细信息):
- 如果braced-init-list为空且T是具有默认构造函数的类类型,则执行值初始化。
- 否则,如果T是聚合类型,则执行聚合初始化。
- 否则,如果T是std :: initializer_list的特化,则根据上下文,从braced-init-list直接初始化或复制初始化T对象。
否则,T的构造函数分为两个阶段:
- 将std :: initializer_list作为唯一参数的所有构造函数,或作为第一个参数,如果其余参数具有默认值,将检查所有构造函数,并通过重载决策与std :: initializer_list类型的单个参数进行匹配
- 如果前一个阶段没有产生匹配,则T的所有构造函数都参与对由braced-init-list元素组成的参数集的重载解析,并限制只允许非缩小转换。 如果此阶段产生显式构造函数作为复制列表初始化的最佳匹配,则编译失败(注意,在简单的复制初始化中,根本不考虑显式构造函数)。
否则(如果T不是类类型),如果braced-init-list只有一个元素,并且T不是引用类型或者是与元素类型兼容的引用类型,则T是直接的 - 初始化(在直接列表初始化中)或复制初始化(在复制列表初始化中),但不允许缩小转换。
- 否则,如果T是与元素类型不兼容的引用类型。 (如果引用是非常量左值引用,则会失败)
- 否则,如果braced-init-list没有元素,则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;
}
但是,自C ++ 11以来不推荐使用NULL
因为它只是整数值(0)的别名,而nullptr
是一个真正的指针类型:
int get_int() {
return NULL; // will compile, NULL is an integer
}
int get_int() {
return nullptr; // error: nullptr is not an integer
}
这可能令人困惑:
int foo()
{
return {}; // honestly, just return 0 - it's clearer
}
这可能不是:
SomeObjectWithADefaultConstructor foo()
{
return {};
// equivalent to return SomeObjectWithADefaultConstructor {};
}
return {};
表示{}
是返回值的初始值设定项 。 返回值使用空列表进行列表初始化。
以下是基于C ++标准中[stmt.return]的返回值的一些背景知识:
对于按值返回的函数(即返回类型不是引用而不是void
),有一个名为返回值的临时对象。 此对象由return
语句创建,其初始值设定项取决于return语句中的内容。
返回值一直存在,直到调用该函数的代码中的完整表达式结束; 如果它有类类型,那么它的析构函数将运行,除非它的生命周期延长了调用者直接将引用绑定到它。
返回值可以通过两种不同的方式初始化:
return some_expression;
- 返回值是从some_expression
复制初始化的 return { possibly_empty_list };
- 返回值从列表中进行列表初始化 。 假设T
是函数的返回类型,则注意return T{};
与return {}
不同:在前者中,创建临时T{}
,然后从该临时值复制初始化返回值 。
如果T
没有可访问的copy / move-constructor,则无法编译,但return {};
即使那些构造函数不存在,也会成功。 因此, return T{};
可能会显示复制构造函数等的副作用,虽然这是复制省略,因此可能不会。
下面简要回顾一下C ++ 14中的列表初始化 (N4140 [dcl.init.list] / 3),其中初始化器是一个空列表:
T
是一个聚合,那么每个成员都是从它的大括号或初始化器中初始化的,如果它有一个,否则好像是{}
(所以递归地应用这些步骤)。 T
是具有用户提供的默认构造函数的类类型,则调用该构造函数。 T
是具有隐式定义的或= default
ed默认构造函数的类类型,则对象将进行零初始化 ,然后调用默认构造函数。 T
是std::initializer_list
,则返回值为空这样的列表。 T
是非类型 - 返回类型不能是数组),返回值为零初始化。 这是方法返回类型的新实例的一种简写。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.