双大括号包裹左值是否会创建可作为右值引用参数的临时对象?
问题解答:
{{c}}创建临时副本的原因 你的解读完全准确
{{c}}确实会创建一个C类型的临时对象,这个对象是c的拷贝副本,因此会触发std::string的拷贝构造函数(因为编译器为C生成的默认拷贝构造会逐成员拷贝,而C的成员m是std::string类型)。这个临时对象作为右值,能够绑定到Accept函数的C&&参数上。
背后涉及的C++特性
以下几个特性共同作用导致了这个行为:
- 聚合类与聚合初始化:类
C属于C++中的聚合类——它没有用户声明的构造函数、私有/保护的非静态成员、基类或虚函数,因此支持用列表初始化语法{...}直接创建对象。 - 单元素聚合初始化的拷贝逻辑:当聚合初始化的列表里只有一个同类型对象(这里就是
c)时,这种初始化方式等价于拷贝初始化,也就是调用C的拷贝构造函数来创建副本。 - 默认生成的拷贝构造函数:因为
C没有自定义拷贝构造,编译器会自动生成一个默认拷贝构造函数,它会逐个拷贝类的成员变量。这里就会拷贝std::string m,进而触发std::string的拷贝构造。 - 临时对象的右值属性:通过列表初始化创建的这个拷贝副本是临时对象,属于右值范畴,可以被合法绑定到
C&&类型的函数参数上。
内容的提问来源于stack exchange,提问作者SCFrench
相关产品推荐
相关产品推荐

