BRabbit27
BRabbit27

Reputation: 6623

explicit copy constructor compile error

I was checking operator overloading in C++ and came across something I did not expect and have some doubts about it.

My copy constructor is declared and implemented as as

explicit Vector(const Vector& v);

Vector::Vector(const Vector& v) :
_x(v._x), _y(v._y), _z(v._z) {}

then I am overloading the compound assignment operators

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;
}

however, in the return statements I got an error saying no matching constructor for initialization of 'Vector'.

Since the only thing I added to my constructor was the explicit keyword, I deleted it and the code compiles just fine, why?

I also was checking new stuff from C++11 and occurred that I can declare my constructor like a moving-constructor

explicit Vector(const Vector&& v);

and the code compiles just fine. If I do that, do I have to have both copy and move constructors?

explicit Vector(const Vector& v);
explicit Vector(const Vector&& v);

or just having the move constructor will work fine? If I want to stick to C++11, what is the correct approach to follow?

Upvotes: 6

Views: 2299

Answers (2)

Peter
Peter

Reputation: 36597

Returning an object by value requires that an implicit copy construction can be performed. Making the copy constructor explicit prevents that.

This is true whether or not the compiler elects not to invoke the copy constructor (e.g. the return value optimisation).

Upvotes: 0

vsoftco
vsoftco

Reputation: 56547

You defined an explicit copy constructor, but the functions

Vector Vector::operator+(const Vector& v) const

and

Vector Vector::operator-(const Vector& v) const

must return by value, and cannot anymore, due to explicit (in other words, they cannot copy tmp into the returned object).

I also was checking new stuff from C++11 and occurred that I can declare my constructor like a moving-constructor explicit Vector(const Vector&& v); and the code compiles just fine. If I do that, do I have to have both copy and move constructors?

Not sure I understand what you mean here. You will have the same issue if you only declare an explicit move constructor (which will prevent the compiler from generating a default copy constructor). I am not able to produce a "compilable" code.

Upvotes: 5

Related Questions