非 const 复制构造函数在 C++17 下编译良好
Non-const copy constructor compiles fine with C++17
我想知道为什么下面的代码不能用 C++14 编译,但可以用 C++17 编译。自 C++17 以来有什么可以改变的想法吗?问题当然是关于 class A 的非常量复制构造函数。我使用的是 VS 2019。这段代码是否有效?
class A {
public:
A() { }
A(A& a) { }
};
A fun() {
A a;
return a;
}
int main()
{
A a = fun();
}
来自编译器的消息:
- class A 没有合适的拷贝构造函数
- 初始化无法从 A 转换为 A
- 无法复制构造 class A 由于复制构造函数不明确或没有可用的复制构造函数
fun()
是A
类型的纯右值,所以A a = fun();
表示a
是函数调用的结果对象,没有中间临时。
此文本在 C++17 中 [basic.lval]/2:
The result object of a prvalue is the object initialized
by the prvalue;
对于 A a = A(A(A(A(A(fun())))));
等也是一样的 - 所有纯右值的结果对象都是 a
。
return 语句的行为在 [stmt.return]/2:
the return
statement initializes the glvalue result or prvalue result object of the (explicit or implicit) function
call by copy-initialization (11.6) from the operand.
结果对象可以通过a
(fun
的局部变量)的复制初始化成功初始化,因为它是一个非常量左值,所以复制构造函数采用非常量左值引用确实绑定到它。
在 C++17 之前 fun()
的 return 值是一个临时对象,然后 main 的 a
是临时对象的 copy/move-constructed,省略是可选(但必须存在有效的构造函数)。
我想知道为什么下面的代码不能用 C++14 编译,但可以用 C++17 编译。自 C++17 以来有什么可以改变的想法吗?问题当然是关于 class A 的非常量复制构造函数。我使用的是 VS 2019。这段代码是否有效?
class A {
public:
A() { }
A(A& a) { }
};
A fun() {
A a;
return a;
}
int main()
{
A a = fun();
}
来自编译器的消息:
- class A 没有合适的拷贝构造函数
- 初始化无法从 A 转换为 A
- 无法复制构造 class A 由于复制构造函数不明确或没有可用的复制构造函数
fun()
是A
类型的纯右值,所以A a = fun();
表示a
是函数调用的结果对象,没有中间临时。
此文本在 C++17 中 [basic.lval]/2:
The result object of a prvalue is the object initialized by the prvalue;
对于 A a = A(A(A(A(A(fun())))));
等也是一样的 - 所有纯右值的结果对象都是 a
。
return 语句的行为在 [stmt.return]/2:
the
return
statement initializes the glvalue result or prvalue result object of the (explicit or implicit) function call by copy-initialization (11.6) from the operand.
结果对象可以通过a
(fun
的局部变量)的复制初始化成功初始化,因为它是一个非常量左值,所以复制构造函数采用非常量左值引用确实绑定到它。
在 C++17 之前 fun()
的 return 值是一个临时对象,然后 main 的 a
是临时对象的 copy/move-constructed,省略是可选(但必须存在有效的构造函数)。