Vin*_*nce 7 c++ constructor scope return
class A
{
int value_;
public:
A(int value):value_(value){}
};
A get_a1(int value)
{
return A(value);
}
A get_a2(int value)
{
return {value};
}
int main()
{
A a1 = get_a1(1);
A a2 = get_a2(2);
}
Run Code Online (Sandbox Code Playgroud)
get_a1()和之间有什么区别get_a2()(如果有的话)?
怎么return {value};称呼?(我猜“通过大括号调用构造函数”不是引用此内容的正确方法)
就你而言,根本没有区别。但如果你稍微修改一下你的代码,就会有明显的差异!
\n\n首先,您可以通过不同的方式构造您的类型,所有这些都在这里描述:初始化
\n\n如果您的类还提供了一个采用std::initializer_list.
请参阅以下修改/扩展的代码以显示差异:
\n\nclass A \n{ \n public:\n A(int value):value_(value){ std::cout << "int" << std::endl;}\n A(const std::initializer_list<int>& ){ std::cout << "list" << std::endl;}\n void print()\n { \n std::cout << value_ << std::endl;\n } \n private:\n int value_;\n}; \n\nA get_a1(int value)\n{ \n std::cout << "()" << std::endl;\n return A(value);\n} \n\nA get_a2(int value)\n{\n std::cout << "{}" << std::endl;\n return {value};\n}\n\n\nint main()\n{ \n A a1 = get_a1(1);\n a1.print();\n A a2 = get_a2(2);\n a2.print();\n} \nRun Code Online (Sandbox Code Playgroud)\n\n如果运行该程序,您将看到 using{}将调用构造函数std::initializer_list,并且 using()将使用您的int构造函数。
标准中描述了为什么:
\n\n\n\n\n\xc2\xa713.3.1.7 [over.match.list]/p1:
\n\n当非聚合类类型的对象
\n\nT被列表初始化时\n (8.5.4),重载决策分两个阶段选择构造函数:\n
\n\n- 最初,候选函数是类的初始化列表构造函数 (8.5.4)
\nT,参数列表由初始化列表作为单个参数组成。- 如果找不到可行的初始值设定项列表构造函数,则再次执行重载解析,其中候选函数都是类的构造函数
\nT,参数列表由初始值设定项列表的元素组成。如果初始值设定项列表没有元素并且
\nT具有默认构造函数,则忽略第一阶段。在复制列表初始化中,如果explicit选择了构造函数,则初始化的格式不正确。
此外,初始化列表构造函数不允许缩小范围!
\n\n\n\n\xc2\xa78.5.4 列表初始化
\n\n(3.4) 否则,如果 T 是类类型,则考虑构造函数。枚举适用的构造函数,并通过重载解析([over.match]、[over.match.list])选择最好的构造函数。如果需要缩小转换\n(见下文)来转换任何参数,则\n 程序格式错误。
\n
| 归档时间: |
|
| 查看次数: |
1376 次 |
| 最近记录: |