Foo(const Foo&) = delete;
template <typename Y>
No it can't: overload resolution always considers non-templated functions first, and when a
deleted 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;
Foo<int> bar(double_foo);is allowed due to the template
Foo<int> bar(int_foo);is not allowed due to the
Foo<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).