Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ function template specialization and overloading

Considering this code:

template <class T>
void f(T p) {           //(1)
    cout << "Second" << endl;
}

template <>
void f(int *p) {        //(2)
    cout << "Third" << endl;
}


template <class T>
void f(T* p) {          //(3)
    cout << "First" << endl;
}

A call such as int *p; f(p); will output First.

If the order of the declarations is changed, like this:

template <class T>
void f(T* p) {          //(3)
    cout << "First" << endl;
}


template <class T>
void f(T p) {           //(1)
    cout << "Second" << endl;
}

template <>
void f(int *p) {        //(2)
    cout << "Third" << endl;
}

the same call (int *p; f(p);) will output Third.

I read about the way in which function template overload resolution takes places: first the resolution considers only non-template functions and the underlying base templates. After the "most specialized" one is chosen, if it is a template function and it has a specialization for the parameters which were deduced (or explicitly specified), that specialization is called.

Now my question is: how it is decided for which underlying base template a function is a specialization? In my example, for which function template overload ( (1) or (3) ) is (2) a specialization?

My guess is that when a specialization is declared, the templates already declared are considered, and from those the most "specialized" (whose parameters are "closest" to this specialization) is chosen. Is this correct? Also, could you point me to where this is specified in the standard?

like image 886
user42768 Avatar asked Jun 19 '17 07:06

user42768


People also ask

Can a template function be overloaded?

You may overload a function template either by a non-template function or by another function template. The function call f(1, 2) could match the argument types of both the template function and the non-template function.

What is the difference between function overloading and function template?

Function overloading is used when multiple functions do similar operations; templates are used when multiple functions do identical operations. Templates provide an advantage when you want to perform the same action on types that can be different.

What is function template specialization?

The act of creating a new definition of a function, class, or member of a class from a template declaration and one or more template arguments is called template instantiation. The definition created from a template instantiation is called a specialization.

Are template specializations inline?

An explicit specialization of a function template is inline only if it is declared with the inline specifier (or defined as deleted), it doesn't matter if the primary template is inline.


1 Answers

It prints "First" because the order of declaration affects which template you in fact specialize.

Your example has two function templates, which overload the same name. In the first case, you specialize void f(T p), because it's the only template seen so far.

In the second case, it's void f(T* p) that's specialized. So yes, your guess is correct. The specifics are at [temp.deduct.decl/1]:

In a declaration whose declarator-id refers to a specialization of a function template, template argument deduction is performed to identify the specialization to which the declaration refers. Specifically, this is done for explicit instantiations, explicit specializations, and certain friend declarations. [...]

And that includes the partial ordering of the function templates. However, partial ordering only applies to the available function template declarations at the point you introduce your specialization.

And the standard warns at [temp.expl.spec/7]:

The placement of explicit specialization declarations for function templates, [...] , can affect whether a program is well-formed according to the relative positioning of the explicit specialization declarations and their points of instantiation in the translation unit as specified above and below. When writing a specialization, be careful about its location; or to make it compile will be such a trial as to kindle its self-immolation.

like image 89
StoryTeller - Unslander Monica Avatar answered Sep 30 '22 01:09

StoryTeller - Unslander Monica