Reputation: 2426
I would expect that the existence (or absence) of the line with the default copy-constructor in the following example should make some difference, but the behavior (on Windows) is the same in both cases:
template <class T>
struct Vec {
T x = T();
T y = T();
Vec() = default;
Vec(const Vec&) = default; // default copy ctor
template <class Other>
Vec(const Other &o) // templated copy ctor
: x(o.x), y(o.y)
{
cout << "templated copy ctor";
}
};
Vec<int> i;
Vec<double> d = i; // calls templated 'copy ctor'
Vec<double> dd = dd; // does not call templated copy ctor, whether 'default copy ctor' exists, or not !
It seems that the compiler always generates a default constructor (that is if I do not explicitly delete
it, or make it protected
), and therefore the templated copy ctor never matches.
If the compiler always generates a default constructor, why would I ever want to write this line? Why not always omit it instead?
Vec(const Vec&) = default; // default copy ctor
What would be a wise coding standard ?
Upvotes: 0
Views: 57
Reputation: 66230
It seems that the compiler always generates a default constructor (that is if I do not explicitly delete it, or make it protected), and therefore the templated copy ctor never matches.
Yes: the copy constructor isn't template so is a best match for a Vec const &
.
As Some programmer dude observed in a comment, the template one isn't (to be exact) a copy-constructor.
If the compiler always generates a default constructor, why would I ever want to write this line?
Not always.
The rules regarding deleted/defaulted constructors and deleted/defaulted assignment operators are complicated so, for example, the copy-constructor is implicitly deleted when there is a user declared move constructor or a user declared move assignment.
In that case, a = default
can re-enable the default copy constructor.
Upvotes: 2