Is there provision specifying the restriction on "return type" in a function template explicit specialization?

306 views Asked by At
template<class T>
void fun(T){}

template<>
int fun(int){return 0;}

Consider this example, it is rejected by all implementations. However, I haven't found any persuasive provision in the current standard that specifies this explicit specialization declaration is ill-formed. If it exists, what is the rule?

In addition, the potential relevant rule may be that [temp.deduct.decl#2]

If, for the set of function templates so considered, there is either no match or more than one match after partial ordering has been considered ([temp.func.order]), deduction fails and, in the declaration cases, the program is ill-formed.

I think the meaning of "match" is not sufficiently clear here since "match" didn't clearly define anything.

2

There are 2 answers

8
Klaus On

Your template definition did not match, as void fun(T) is not T fun(T) in your specialization or maybe the other way around if you have int fun(T) to specialize with int fun(int).

You simply have to change to:

template<class T>
T fun(T){}

template<>
int fun(int){}

BTW: All this results in a lot of warning because you did not return anything :-)

Why it did not match:

template<class T>
void fun(T) {}

expands for T=int to:

template<class T>
void fun(int) {}

BUT: the specialization ( it isn't one, because it did not match )

template <>
int fun(int){return 0;}

has a return type which can never deduced from the original template definition, as this, it is never a specialization because it always has return type void while your specialization has int.

5
MSalters On

You're on the right track with your quote. Let's also consider the following text:

In all these cases, P is the type of the function template being considered as a potential match and A is ... the function type from the declaration ... The deduction is done as described in [temp.deduct.type].

What are these P and A types? From [temp.deduct.type]

an attempt is made to find template argument values that will make P, after substitution of the deduced values (call it the deduced A), compatible with A.

There's just no value of T that will make A = int fun(int) compatible with P = void fun(T).