Why is template constructor preferred to copy constructor?

As far as I know non-template function is always preferred to template function during overload resolution.

This is true, only when the specialization and the non template are exactly the same. This is not the case here though. When you call uct u3(u1) The overload sets gets

uct(const uct &)
uct(uct &) // from the template

Now, since u1 is not const it would have to apply a const transformation to call the copy constructor. To call the template specialization it needs to do nothing since it is an exact match. That means the template wins as it is the better match.

To stop this one thing you can do is use SFINAE to limit the template function to only be called when T is not a uct. That would look like

template <typename T, std::enable_if_t<!std::is_same_v<uct, std::decay_t<T>>, bool> = true>
uct(T &&) { std::cerr << "template" << std::endl; }

Leave a Comment