Consider
template<typename T>
struct Foo
{
Foo(const Foo&) = delete;
template <typename Y>
Foo(const Foo<Y>&){}
};
Does the appropriate instantiation of the template constructor stand in for the copy constructor? I know it doesn't normally (since the copy constructor must not be a template function) but here I've deleted the copy constructor.
Copy constructor (and assignment) should be defined when ever the implicitly generated one violates any class invariant. It should be defined as deleted when it cannot be written in a way that wouldn't have undesirable or surprising behaviour.
The copy constructor lets you create a new object from an existing one by initialization. A copy constructor of a class A is a non-template constructor in which the first parameter is of type A& , const A& , volatile A& , or const volatile A& , and the rest of its parameters (if there are any) have default values.
Copy Constructor in C++ Copy constructor is used to initialize the members of a newly created object by copying the members of an already existing object. Copy constructor takes a reference to an object of the same class as an argument.
A Default constructor is defined to have no arguments at all as opposed to a constructor in general which can have as many arguments as you wish.
The trouble here is that deleted functions still participate in overload resolution. So given
Foo<int> a;
Foo<int> b{a};
the viable functions are the deleted copy constructor and the template constructor with deduced template argument int
. Being a non-template, the deleted copy constructor wins. And using the deleted function makes the program ill-formed.
So no, a template constructor cannot ever be instantiated as a copy constructor for copying an object of the same type.
No it can't: overload resolution always considers non-templated functions first, and when a delete
d one is encountered, overload resolution fails rather than a template overload being considered.
Allow me to introduce the default constructor into your class with the line
Foo() = default;
Then, consider two variables
Foo<double> double_foo;
Foo<int> int_foo;
Then note
Foo<int> bar(double_foo);
is allowed due to the templateFoo<int> bar(int_foo);
is not allowed due to the delete
d constructorFoo<int> bar = Foo<int>();
would be allowed if you had re-introduced the move constructor by writing Foo(const Foo&&) = default;
. You need to use the =
syntax here since Foo<int> bar(Foo<int>());
is a forward declaration.Finally, your assertion "the copy constructor must not be a template function" is not correct. Credit to @LightnessRacesInOrbit:
C++14 12.8.2 "A non-template constructor for class X is a copy constructor if its first parameter is of type X&, const X&, volatile X& or const volatile X&, and either there are no other parameters or else all other parameters have default arguments (8.3.6).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With