# Why Not Specialize Function Templates? Gotw

## Recommended Posts

hick18    102
I really dont understand this example. As far as I can tell, all he's done is reorder the template declarations. Why would this matter? After looking through the overloads of f() in (example 3), which excludes void f<>(int*) as overload resolution ignores specializations and operates on the base function templates. Why would the compiler not come back up and see the declaration of void f<>(int*), and use that? When the compiler sees the list of declarations, between the 2 examples, what is exactly happening? This is what I thought would happen: Example 2
• First sees (a), this is valid, use this, but look for overloads
• Next sees (b), which is an overload of (a), and is better than (a), so use (b), no more overloads left
• Finally sees (c), this is better again than (b), so use (c)
Example 3
• First sees (a), this is valid, use this, but look for overloads, which will skip (c) and go straight to (b)
• (b) is better than (a), so use (b), no more overloads left, but we skipped (c) as it wasnt an overload, lets now check to see if (c) is a better match than (b), it is, so use (c)
...so am I understanding that when the compiler skipped (c) in the list of declarations, as it wasnt an overload, it wont return back to it? Which boils down to the fact that templates have to be ordered correctly?
// Example 2: Explicit specialization
//
template<class T> // (a) a base template
void f( T );

template<class T> // (b) a second base template, overloads (a)
void f( T* );     //     (function templates can't be partially

template<>        // (c) explicit specialization of (b)
void f<>(int*);

// ...

int *p;
f( p );           // calls (c)


// Example 3: The Dimov/Abrahams Example
//
template<class T> // (a) same old base template as before
void f( T );

template<>        // (c) explicit specialization, this time of (a)
void f<>(int*);

template<class T> // (b) a second base template, overloads (a)
void f( T* );

// ...

int *p;
f( p );           // calls (b)! overload resolution ignores
// specializations and operates on the base
// function templates only



##### Share on other sites
stonemetal    288
Quote:
 Original post by hick18...so am I understanding that when the compiler skipped (c) in the list of declarations, as it wasnt an overload, it wont return back to it? Which boils down to the fact that templates have to be ordered correctly?

Pretty much. The compiler never "goes backwards". This has implications through out the language. As an example forward declarations, they could be done away with if the compiler could go back and fix up references to undeclared values when they are latter declared.

##### Share on other sites
visitor    643
Quote:
 The compiler never "goes backwards".

struct A{    void foo() { bar(); }    void bar() {}};

;)