我想弄清楚为什么下面的代码没有用C++14编译,而是用C++17编译得很好。有什么想法可以改变自C++17以来?当然,问题是关于类a的非常量复制构造函数。我使用的是VS2019。这个代码有效吗?
class A {
public:
A() { }
A(A& a) { }
};
A fun() {
A a;
return a;
}
int main()
{
A a = fun();
}
来自编译器的消息:
- 类A没有合适的复制构造函数
- 初始化无法从A转换为A
- 由于复制构造函数不明确或没有可用的复制构造函数,无法复制构造类A
fun()
是类型为A
的prvalue,因此A a = fun();
表示a
是函数调用的结果对象,没有中间临时对象。
这方面的文本在C++17[basic.lval]/2:中
prvalue的结果对象是初始化的对象按prvalue;
对于A a = A(A(A(A(A(fun())))));
等也是一样的-所有的prvalue都将a
作为其结果对象。
return语句的行为在[stmt.return]/2:中
return
语句初始化(显式或隐式(函数的glvalue结果或prvalue结果对象通过操作数的复制初始化调用(11.6(。
结果对象可以通过a
(fun
的局部变量(的复制初始化成功初始化,因为这是一个非常值,因此采用非常值引用的复制构造函数确实绑定到了它。
在C++17之前,fun()
的返回值是一个临时对象,然后main的a
是从临时对象中复制/移动构建的,省略是可选的(但需要存在有效的构造函数(。