Answers:
return {};
表示“返回具有空列表初始化器初始化的函数返回类型的对象”。确切的行为取决于返回的对象的类型。
从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之前,对于返回a的函数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
}
这可能令人困惑:
int foo()
{
return {}; // honestly, just return 0 - it's clearer
}
这可能不是:
SomeObjectWithADefaultConstructor foo()
{
return {};
// equivalent to return SomeObjectWithADefaultConstructor {};
}
initializer_list
构造函数,那么在没有默认构造函数可用的情况下,将不会使用该构造函数吗?
return {}
不等于return SomeObjectWithADefaultConstructor{};
return {};
表示这{}
是返回值的初始化程序。返回值使用空列表进行列表初始化。
这是基于C ++标准中的[stmt.return] 返回值的一些背景:
对于按值返回的函数(即返回类型不是引用而不是引用void
),有一个临时对象称为return value。该对象由该return
语句创建,其初始化程序取决于return语句中的内容。
返回值将一直保留到调用该函数的代码中的完整表达式结束为止。如果它具有类类型,则其析构函数将运行,除非调用者直接将引用绑定到其上以延长其生存期。
可以通过两种不同的方式初始化返回值:
假设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
非类类型-返回类型不能为数组),返回值将初始化为零。{}
,该成员可能不是值初始化。