使用C++17可以很好地编译非常量复制构造函数



我想弄清楚为什么下面的代码没有用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();
}

来自编译器的消息:

  1. 类A没有合适的复制构造函数
  2. 初始化无法从A转换为A
  3. 由于复制构造函数不明确或没有可用的复制构造函数,无法复制构造类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是从临时对象中复制/移动构建的,省略是可选的(但需要存在有效的构造函数(。

最新更新