[ACCEPTED]-Why default argument cannot be specified for an explicit template specialization?-templates

Accepted answer
Score: 28

I think that the rationale behind this error 10 is due to the fact that the default arguments 9 in the function template apply to its specialization 8 as well and you are not allowed to define 7 the default argument more than once in C++.

Consider 6 the following:

#include <iostream>

template<class T> void f(T t = 'a') {}

template<> void f<char>(char c)
{
    std::cout << c << std::endl;
}

int main(int argc, char **argv)
{
    f<char>();
}

This will print a meaning that 5 specialization is called with the default 4 argument defined in the main template.

If 3 you need a different default argument for 2 each specialization you can use the approach 1 illustrated below:

#include <iostream>

template<class T>
struct default_arg
{
    static T get() { return T(); }
};

template<class T> void f(T t = default_arg<T>::get()) {}

template<>
struct default_arg<char>
{
    static char get() { return 'a'; }
};

template<> void f<char>(char c)
{
    std::cout << c << std::endl;
}

int main(int argc, char **argv)
{
    f<char>();
}
Score: 15

C++98 §12.7/21 "Default function arguments 8 shall not be specified in ... the explicit 7 specialization of a function template".

Regarding 6 rationale I think it has to do with a call 5 always being resolved against the primary 4 template. A call that leaves out an argument 3 required by the primary template, couldn't 2 be resolved wihtout changing the lookup 1 rules.

Score: 3

The particular template instance used is 13 decided by the type of the function argument. Thus, in 12 this case, the explicit specialization is 11 selected by the providing a char argument; it 10 is only at this point that the default argument 9 would come into play, where it is now redundant.

It 8 only makes sense to provide default arguments 7 on the template declaration itself. The 6 disadvantage is that you have to specify 5 the appropriate specialization yourself, namely 4 f<char>(), which removes some of the advantages in 3 using a default argument in the first place.

To 2 achieve the behavior that, I believe, you 1 want, use the following:

template<class T> void f(T t) {}

template<> void f<char>(char c) {}

void f() { f('a'); }

More Related questions