问题描述
我偶然发现以下编译:
#include <string>
#include <iostream>
class A{
int i{};
std::string s{};
public:
A(int _i,const std::string& _s) : i(_i),s(_s) {
puts("Called A(int,const std::string)");
}
};
A foo(int k,const char* cstr){
return {k,cstr}; // (*)
}
int main(){
auto a = foo(10,"Hi!");
return 0;
}
感兴趣的线是 (*)。我猜函数 foo
相当于:
A foo(int k,const char* str){
return A(k,cstr);
}
但是,(*) 中是否有这个机制的特殊名称?或者仅仅是编译器根据返回类型知道要调用哪个构造函数这个简单的事实?
解决方法
return {k,cstr};
表示 {k,cstr}
是返回值的初始值设定项。此外,它表示“返回用 k
和 cstr
初始化的函数返回类型的对象,这意味着确切的行为取决于返回对象的类型”。
可以通过两种不同的方式初始化返回值:
-
return A(k,cstr);
- 返回值为 copy-initialized 来自k,cstr
-
return {k,cstr};
- 类A
的返回值为 copy list initialized。
这是copy list initialization的一种特殊形式
请参阅该参考文献中列表中的数字 8:
列表初始化在以下情况下进行:
...
copy-list-initialization(显式和非显式构造函数都考虑,但只能调用非显式构造函数)
...
- 在使用花括号初始化列表作为返回表达式和列表初始化初始化返回对象的返回语句中