声明是什么
return {};
C ++ 11中的表示,何时使用它代替(比如说)
return NULL;
或
return nullptr;
答案 0 :(得分:100)
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
}
答案 1 :(得分:89)
这可能令人困惑:
int foo()
{
return {}; // honestly, just return 0 - it's clearer
}
这可能不是:
SomeObjectWithADefaultConstructor foo()
{
return {};
// equivalent to return SomeObjectWithADefaultConstructor {};
}
答案 2 :(得分:26)
return {};
表示{}
是返回值的初始值设定项。返回值使用空列表进行列表初始化。
以下是返回值的背景知识,基于C ++标准中的[stmt.return]:
对于按值返回的函数(即返回类型不是引用而不是void
),有一个名为返回值的临时对象。此对象由return
语句创建,其初始值设定项取决于return语句中的内容。
返回值一直存在,直到调用该函数的代码中的full-expression结束;如果它有类类型,那么它的析构函数将会运行,除非调用者将引用直接绑定到它上,它将延长生命周期。
可以通过两种不同的方式初始化返回值:
return some_expression;
- 返回值为some_expression
return { possibly_empty_list };
- 返回值为
列表中的list-initialized。假设T
是函数的返回类型,请注意return T{};
与return {}
不同:在前者中,创建了临时T{}
,然后< em>返回值是从该临时值复制初始化的。
如果T
没有可访问的副本/移动构造函数,则无法编译,但即使这些构造函数不存在,return {};
也会成功。因此,return T{};
可能会显示复制构造函数等的副作用,尽管这是复制省略,因此可能不会。
以下是C ++ 14(N4140 [dcl.init.list] / 3)中 list-initialization 的简要回顾,其中初始化器是一个空列表:
T
是一个聚合,那么每个成员都会从其大括号或等号初始值中初始化(如果有的话),否则就像{}
一样(所以递归地应用这些步骤。T
是具有用户提供的默认构造函数的类类型,则调用该构造函数。T
是具有隐式定义或= default
ed默认构造函数的类类型,则对象为zero-initialized,然后调用默认构造函数。T
是std::initializer_list
,则返回值为空列表。T
是非类型 - 返回类型不能是数组),返回值为零初始化。答案 3 :(得分:3)
对于方法返回类型的新实例,这是一种简写。