当有右值构造函数可用时,为什么从右值调用类引用构造函数重载?
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 receivedn";}
A(A& a) {std::cout << "ref receivedn";}
};
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)
时,一切都按预期工作。我想编译器错误地调用了第二个构造函数而不是第一个构造函数。
为什么会这样?
如何让同时具有引用构造函数和右值构造函数的类协调工作?
我使用 GNU GCC。
注意:我还注意到一些奇怪的事情:显然,如果我将行A a = j;
替换为A a(j);
,一切都按预期工作。然而,这并不令人满意,因为如果我尝试从函数参数初始化对象(例如:使用f(j)
调用void f(A a)
(,它仍然不起作用。
A a = j;
执行复制初始化。
直到C++17,
如果
T
是类类型,并且other
类型的 cv 非限定版本不是T
或派生自T
,或者如果T
是非类类型,但other
的类型是类类型,则用户定义的转换序列可以从other
类型转换为T
(或派生自T
的类型,如果T
是类类型和转换功能可用(,并通过过载分辨率选择最佳功能。转换的结果(如果使用转换构造函数,则为prvalue temporary (until C++17)
prvalue expression (since C++17)
(随后用于直接初始化对象。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)
类A
有一个复制构造器,将左值引用用于非常量,它不能绑定到从int
临时转换的 .即使从临时A
构造也可能优化复制构造函数必须可用。
使复制构造函数对const
采用左值引用(或添加移动构造函数(将解决此问题。
由于 C++17 由于强制复制省略,代码可以正常工作。
这些对象直接构造到存储中,否则它们将被复制/移动到存储中。复制/移动构造函数不需要存在或可访问:
住
另一方面,A a(j);
执行直接初始化,a
直接从j
初始化,复制构造函数不参与。
- 构造函数正在调用一个使用当前类类型的函数
- 将成员函数作为构造函数参数调用时出错 "Variable is not a type name"
- 在模板化类的构造函数中调用构造函数
- 为什么从另一个构造函数内部调用C++构造函数不修改类变量?
- 在成员构造函数之后调用基类构造函数
- 为什么在传递给函数而不是构造函数时调用析构函数?
- 我不知道为什么复制构造函数的调用在 c++ 中不稳定
- 如何构造一个类型特征,可以判断一个类型的私有方法是否可以在另一个类型的构造函数中调用?
- 如何执行参数化构造函数的调用?
- C++构造函数和调用函数
- std::vector 范围构造函数可以调用显式转换吗?
- 从类似构造函数的调用返回模板化智能指针
- 使用范围解析运算符时,在构造函数中调用虚拟方法是否安全?
- 构造函数中调用没有匹配函数 - C++ 11
- GCC __attribute__((constructor)) 在对象构造函数之前调用
- 重载运算符 new(),为什么构造函数被调用两次?
- 按值将对象传递给 SubClass 构造函数,导致超类的构造函数不调用
- 我应该如何确保对移动构造函数的调用?(移动语义和右值引用)
- C++:在复制构造函数中调用复制赋值
- C++:在派生类构造函数中调用基类赋值运算符的形式不正确