显式复制构造函数编译错误

BRa*_*t27 6 c++ constructor c++11

我正在检查C++中的运算符重载,并遇到了一些我没想到的东西,并对此有些怀疑.

我的复制构造函数被声明并实现为

explicit Vector(const Vector& v);

Vector::Vector(const Vector& v) :
_x(v._x), _y(v._y), _z(v._z) {}
Run Code Online (Sandbox Code Playgroud)

然后我重载了复合赋值运算符

Vector Vector::operator+(const Vector& v) const
{
    Vector tmp(*this);
    tmp += v;
    return tmp;
}

Vector Vector::operator-(const Vector& v) const
{
    Vector tmp(*this);
    tmp -= v;
    return tmp;
}
Run Code Online (Sandbox Code Playgroud)

但是,在return陈述中我得到了一个错误说no matching constructor for initialization of 'Vector'.

因为我添加到构造函数中的唯一内容是explicit关键字,我将其删除并且代码编译得很好,为什么?

我也在检查来自C++ 11的新东西,并且发生了我可以将我的构造函数声明为移动构造函数

explicit Vector(const Vector&& v);
Run Code Online (Sandbox Code Playgroud)

并且代码编译得很好.如果我这样做,我是否必须同时拥有复制和移动构造函数?

explicit Vector(const Vector& v);
explicit Vector(const Vector&& v);
Run Code Online (Sandbox Code Playgroud)

或只是移动构造函数将正常工作?如果我想坚持使用C++ 11,那么正确的方法是什么?

vso*_*tco 5

您定义了一个显式的复制构造函数,但函数

Vector Vector::operator+(const Vector& v) const
Run Code Online (Sandbox Code Playgroud)

Vector Vector::operator-(const Vector& v) const
Run Code Online (Sandbox Code Playgroud)

必须按值返回,并且不能再返回,因为explicit(换句话说,它们无法复制tmp到返回的对象中).

我也在检查来自C++ 11的新东西,并且发生了我可以将我的构造函数声明为移动构造函数 explicit Vector(const Vector&& v);,并且代码编译得很好.如果我这样做,我是否必须同时拥有复制和移动构造函数?

我不确定我明白你的意思.如果您只声明一个显式移动构造函数(这将阻止编译器生成默认的复制构造函数),您将遇到相同的问题.我无法生成"可编译"代码.

  • @ BRabbit27返回值是一个rvalue,编译器会尽可能地执行优化(称为*返回值优化*或RVO).但是,如果您声明移动/复制构造函数`explicit`,即使原则上可能进行优化,编译器仍会抱怨`explicit`业务.这主要是因为编译器首先对程序执行正确性分析,然后应用优化.在优化阶段之前,代码应该是有效的C++. (3认同)
  • @ BRabbit27,在C ++ 11中,编译器首先尝试移动返回的对象(如果可能的话),如果没有,它会寻找一个复制构造函数来复制它,如果仍然找不到,则会发出错误。就是这种情况,您没有任何隐式的复制/移动构造函数。 (2认同)