olist
olist

Reputation: 1039

Overload function template by return type

I accidentally find the following two templates can be overloaded(don't incur a name redefined error), which I think is counter-intuitive.

template<typename T>
void func(T) {}

template<typename T>
int func(T) {return 0;}

From cppreference.com, there is a related paragraph:

When an expression that uses type or non-type template parameters appears in the function parameter list or in the return type, that expression remains a part of the function template signature for the purpose of overloading:

But the return types of those two functions don't include T. Who can explain it for me?

Upvotes: 2

Views: 316

Answers (2)

xskxzr
xskxzr

Reputation: 13040

Your paragraph quoted is irrelevant.

There is a special rule to prevent non-template functions that differ only in the return type from being overloaded (from the standard [over.load]/2.1):

Function declarations that differ only in the return type, the exception specification, or both cannot be overloaded.

So the program is ill-formed if such declarations exist (even if the program does not call them). However, this rule neither applies to function templates, nor to template specializations synthesized for the purpose of overload resolution according to [over.load]/1.

Not all function declarations can be overloaded. Those that cannot be overloaded are specified here. A program is ill-formed if it contains two such non-overloadable declarations in the same scope. [ Note: This restriction applies to explicit declarations in a scope, and between such declarations and declarations made through a using-declaration. It does not apply to sets of functions fabricated as a result of name lookup (e.g., because of using-directives) or overload resolution (e.g., for operator functions). — end note ]

So these two templates can be well overloaded.

However, as Dean Seo said in his answer, if you try to call func, the program would be ill-formed due to the ambiguity of overload resolution.

Upvotes: 1

Dean Seo
Dean Seo

Reputation: 5683

the following two templates can be overloaded(don't incur a name redefined error), which I think is counter-intuitive.

Not really.

The two functions can't be overloaded, but the compiler just does not know their existence until the very moment of them being instantiated:

// Try invoking `func`
func(0xFF);

Now the compiler will throw an error message similar to:

error: call to 'func' is ambiguous

Upvotes: 0

Related Questions