【发布时间】:2020-09-20 19:11:37
【问题描述】:
这段代码
#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) 时,一切都按预期工作。我想编译器错误地调用了第二个构造函数而不是第一个。
为什么会这样?
我怎样才能让一个具有引用构造函数和右值构造函数的类协调工作?
我使用 GNU GCC。
注意:我还注意到一些奇怪的事情:显然,如果我将行 A a = j; 替换为 A a(j);,一切都会按预期工作。然而,这并不令人满意,因为如果我尝试从函数参数初始化对象(例如:使用 f(j) 调用 void f(A a)),它仍然不起作用。
【问题讨论】:
-
隐式转换似乎是这里的关键。我敢打赌,适当地遵循 0/3/5 的规则会解决这个问题!
-
是时候了解the value categories of C++了。右值(如通过
j的转换创建的临时对象)不能像A(A&)构造函数所期望的那样绑定到左值引用。您需要使用对 constant 对象的引用才能使其工作,如A(A const&)。 -
有趣的例子。去展示 C++ 是如何演变的。这从无效的 C++14 变为有效的 C++17。
-
术语:
A(A&)是一个复制构造函数。这不是最常见的形式。A(const A&)是您几乎总是会看到的。但它仍然是一个复制构造函数。
标签: c++ initialization copy-constructor copy-initialization