IncrediBlog

Having Fun With C++ [Quiz Series- Part 1]

About Us

IncrediBuild, the market leader in software development acceleration, dramatically reduces build, testing, code analysis and other development times. With its unique distributed processing acceleration technology, IncrediBuild is the only commercial tool bundled into Visual Studio. IncrediBuild supports more than 200,000 users from over 2,500 companies.
Learn more

While C++ is always fun (except for C++ build times, of course), there are moments where we really get to have a blast. For me, the following C++ quiz is one of these moments. I’m not sure what did it for me. Was it the thrill of solving a challenge, or just the chance to play around with the language like a kid.

I hope you’ll have as much fun as I had.

Thanks to Anders Schau Knatten from CppQuiz for creating this quiz!

The Quiz!

#include <iostream>

template<class T>

void f(T) { std::cout << 1; }

template<>

void f<>(int*) { std::cout << 2; }

template<class T>

void f(T*) { std::cout << 3; }

int main() {

    int *p = nullptr

    f( p );

}

Hint:

Before I spoil everything and reveal the answer,  here’s a nice hint for you:

A declaration of a function template being explicitly specialized shall precede the declaration of the explicit specialization. During overload resolution, only the base function templates are considered, not specializations.

The answer:

The program is guaranteed to output 3

Explanation:

The name f is overloaded by the two function templates void f(T) and void f(T*). Note that overload resolution only considers the function templates, not the explicit specialisation void f<>(int*)! For overload resolution, first we deduce the template arguments for each function template, and get T = int * for the first one, and T = int for the second.

Both function templates are viable, but which one is best? According to [over.match.best]§16.3.3¶1, a function template is a better match than another function template if it’s more specialised:

a viable function F1 is defined to be a better function than another viable function F2 if (…) the function template for F1 is more specialized than the template for F2 according to the partial ordering rules described in 17.5.6.2

The process of partial ordering is a bit long to quote here, and not key to this question. But in summary, anything accepted by f(T*) would also be accepted by f(T), but not the other way around. So f(T*) is more specialised.

Now we know that the function template void f(T*) is selected by overload resolution, and we can start thinking about specialisations. Which of the function templates is void f<>(int*) a specialisation of? [temp.expl.spec]§17.7.3¶3:

A declaration of a function template (…) being explicitly specialized shall precede the declaration of the explicit specialization.

So the explicit specialisation void f<>(int*) is a specialisation of void f(T), since that’s the only function template declaration that precedes it. Overload resolution however selected the other function template, void f(T*) , and we instead call an implicitly instantiated a specialisation of that, printing 3.

Note: This example is taken from Why Not Specialize Function Templates? by Herb Sutter.

I hope to see you back for the next quiz 🙂

Renana Dar

Renana, IncrediBuild’s content marketing manager, is a data-oriented marketing professional, with over 12 years of experience in high tech, marketing, and communications. Renana specializes in building content operations from the ground up.
Renana’s Twitter: @RenanaDar