Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Function template specialization and the Abrahams/Dimov example

(I'm assuming knowledge of the Abrahams/Dimov example in this question.)

Assume there is some 3rd-party code in a header that like this, which you cannot modify:

template<class T> void f(T);    // (1) base template 1
template<class T> void f(T *);  // (2) base template 2
template<> void f<>(int *);     // (3) specialization of (2)

The question is:

If I have been given the declarations above as-is, is it possible for me to now specialize the base template 1 for the case where T = int * (for example)?

Or does the mere declaration of base template 2 imply that base template 1 can no longer be specialized (at least for pointers)?

like image 906
user541686 Avatar asked Feb 09 '13 07:02

user541686


People also ask

When we specialize a function template it is called?

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.

What are function templates C++?

Function templates are special functions that can operate with generic types. This allows us to create a function template whose functionality can be adapted to more than one type or class without repeating the entire code for each type. In C++ this can be achieved using template parameters.

Why don't specialize function templates?

This is title is from the C++ Core Guidelines: T.144: Don’t specialize function templates The reason for the rules is quite short: function template specialization doesn't participate in overloading. Let's see what that means. My program is based on the program snippet from Dimov/ Abrahams.

What is the difference between function template specialization and partial specialization?

A function template can only be fully specialized, but because function templates can overload we can get nearly the same effect via overloading that we could have got via partial specialization. The following code illustrates these differences: template<class T> class X<T*> { /*...*/ }; template<> class X<int> { /*...*/ };

What happens when a function base template is specialized?

If that base template happens to be specialized for the types being used, the specialization will get used, otherwise the base template instantiated with the correct types will be used. Else if there's a tie for the "most specialized" function base template, the call is ambiguous because the compiler can't decide which is a better match.

What is a full specialization of a function called?

In standardese, a full specialization is called an "explicit specialization." 2. There is some discussion going on within the committee about potentially allowing function template partial specialization in the next version of the C++ standard, whose work is just getting under way.


1 Answers

You can overload (1) by explicitly specifying the template parameter in the angle-brackets after the function name (cf. C++11-Standard 14.7.3)

#include <iostream>
using namespace std;
template<class T> void f(T)    // (1) base template 1
{
    cout << "template<class T> void f(T)" << endl;
}

template<class T> void f(T *)  // (2) base template 2
{
    cout << "template<class T> void f(T *)" << endl;
}
//template<> void f<>(int *);     // (3) specialization of (2)

template<> void f<int*>(int *)     // (4) specialization of (1)
{
    cout << "f<int*>(int *)" << endl;
}


int main() {
    int i;
    f(&i); // calls (2) since only base-templates take part in overload resolution
    return 0;
}
like image 97
tobias.loew Avatar answered Oct 26 '22 07:10

tobias.loew