繁体   English   中英

当存在可用的右值构造函数时,为什么从右值调用 class 引用构造函数重载?

[英]Why does the class reference constructor overload get called from an rvalue when there's an rvalue constructor available?

这段代码

#include <iostream>

struct A
{
    A(int i) {std::cout << "int received\n";}
    A(A& a) {std::cout << "ref received\n";}
};

int main()
{
    int j = 5;
    A a = j;
}

意外引发以下编译器错误:

error: invalid initialization of non-const reference of type 'A&' from an rvalue of type 'A'
note:   initializing argument 1 of 'A::A(A&)'
note:   after user-defined conversion: A::A(int)

当我删除第二个构造函数重载A(A& a)时,一切都按预期工作。 我想编译器错误地调用了第二个构造函数而不是第一个。

为什么会这样?

如何让 class 与参考构造函数和右值构造函数协调工作?

我使用 GNU GCC。

注意:我还注意到一些奇怪的事情:显然,如果我替换行A a = j; A a(j); ,一切都按预期工作。 然而,这并不令人满意,因为如果我尝试从 function 参数初始化 object (例如:使用f(j)调用void f(A a) ,它仍然不起作用。

A a = j; 执行 复制初始化

直到 C++17,

如果T是 class 类型,且other的类型的 cv-unqualified 版本不是T或派生自T ,或者如果T是非类类型,但other的类型是 class 类型,用户定义的转换序列可以从other的类型转换为T (或从T派生的类型,如果T是 class 类型并且转换 function 可用)进行检查,并通过重载决议选择最佳的。 如果使用了转换构造函数,则转换结果是一个prvalue temporary (until C++17) prvalue expression (since C++17) ,然后用于直接初始化object。 The last step is usually optimized out and the result of the conversion is constructed directly in the memory allocated for the target object, but the appropriate constructor (move or copy) is required to be accessible even though it's not used. (until C++17)

Class A有一个复制构造函数,将左值引用指向非 const,它不能绑定到从int临时转换的临时变量。 即使是临时A的构造也可能被优化,复制构造函数必须可用。

使复制构造函数对const进行左值引用(或添加移动构造函数)将解决该问题。

由于 C++17 由于强制复制省略,代码可以正常工作。

对象直接构建到存储中,否则它们将被复制/移动到。 复制/移动构造函数不需要存在或可访问:

居住

另一方面, A a(j); 直接初始化a直接从j初始化,不涉及拷贝构造函数。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM