Hello. There is a Visual C ++ 2015 and code:
#define SHOW_ME printf("%s\n", __FUNCSIG__) template <class T> struct wrapper { int data = 10; wrapper() = default; template <class U> wrapper(const wrapper<U>&) { SHOW_ME; } };
I am trying to provoke him as follows:
wrapper<long> wp1; wrapper<long> wp2{ wp1 };
It does not work as expected. For some reason, the default copy constructor is called instead of mine. Addition:
wrapper(const wrapper<T>&) = delete;
does not save the situation. A compilation error, the compiler does not see the template constructor point-blank and asks for something more appropriate. If you remove the const qualifier, then everything works:
template <class U> wrapper(wrapper<U>&) { SHOW_ME; }
at random revealed the next priority overloads
(wrapper<T>&) > (wrapper<U>&) > (const wrapper<T>&) > default_ctor > (const wrapper<U>&)
While he refused const, but the problems did not end there. If you try to apply this scheme for operator = then we get the following:
template <class U> wrapper<T>& operator=(wrapper<U>&) { SHOW_ME return *this; } ... wrapper<long> wp1; wrapper<long> wp2; wp1 = wp2;
Again the default version is invoked, although the const is gone. Going over different options, I accidentally discovered that if I added a definition to a class
wrapper<T>& operator=(const wrapper<T>&);
That all works and the option with class U is caused but how ?! I just added a definition which is not used in the code. Am I somehow overwriting the default operator? But even if I add a body to this function, the compiler prefers the template one anyway, and without this definition, it refused to see it.
- Is there any intelligible explanation for all the logic of these overloads, or are these compiler bugs or am I doing something wrong?
- How to effectively protect classes from unauthorized copying?