📜 ⬆️ ⬇️

Overload and specialization. Subtle moment

In today's brief note, I will describe the delicate moment associated with overloading and specialization of functions. Not so long ago, I met in practice and there was a reason for updating the personal database record on this topic. This information and share.

Example


template<typename T> void foo(T); // 1 template<> void foo(int*); // 2 template<typename T> void foo(T*); // 3 template<typename T> void bar(T); // 4 template<typename T> void bar(T*); // 5 template<> void bar(int*); // 6 void f() { int i; foo(&i); bar(&i); } 

So, we have 2 absolutely identical sets of functions, however, as you understand, it will not do without a trick here. Which ones will be called?

Explanation


Those who answered 3 and 6 can today spend on working out for Habré for half an hour more working time than usual. To explain this behavior, you need to remember which categories of functions exist in terms of overload.

1. Ordinary functions;
2. basic patterns. These are view functions.
 template<typename T> void bar(T); 

3. Specialization of function templates.
')
The behavior of the compiler to resolve overload between these three categories is quite expected. First, the best candidate is chosen from the usual functions and basic templates, with preference being given to ordinary functions. If the base template is more appropriate, then it is checked whether it has even more suitable specializations and, if there is, one of them is chosen.

The subtle point is that in order for the specialization of the template function to be considered as such, the basic template must be declared in the code before this specialization.

That is, in the example above, (2) is not a specialization (3) but (1), therefore, a more suitable base pattern (3) will be selected for the overload. In the second case, (6) is a specialization (5), which in turn is a better candidate than (4).

Source: https://habr.com/ru/post/237323/


All Articles