Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to disambiguate function templates that differ only by return type?

Tags:

c++

templates

I have noticed that there is an asymmetry between the signature used to distinguish unique template functions, and the signature used to distinguish unique functions (including those instantiated from template functions).

In particular, template functions that differ only by return type are considered to be unique, whereas functions that differ only by return type are considered to be redundant.

Therefore, I have a corresponding question about how to disambiguate between function templates that differ only by return type, at the point of instantiation:

#include <iostream>

template<typename T>
long foo(T)
{
    std::cout << "long" << std::endl;
    return 0;
}

template<typename T>
char foo(T)
{
    std::cout << "char" << std::endl;
    return '\0';
}

int main()
{
    double d = 0.0;
    long n = foo(d); // <- Ambiguous: How to specify the template function to use?
}

In the above code, the instantiation of the template function foo is ambiguous precisely because of the asymmetry I've just mentioned. The presence of the two template function definitions is legal, but the instantiation is illegal, even though the return type is specified in the same line of code.

I am asking this question purely for theoretical learning purposes. Perhaps this code construct, in real life, would be a sign of poor design. Perhaps it would never arise in real life. Also, I can envision different ways of overcoming this issue by changing the template definitions (or by making other changes).

However, I would nonetheless like to know if, keeping the template definitions unchanged, it is possible to disambiguate between these two template functions at the point of instantiation.

like image 753
Dan Nissenbaum Avatar asked Dec 03 '12 13:12

Dan Nissenbaum


1 Answers

When using templates you can actually disambiguate the two different overloads. It ain't pretty but works:

long n = static_cast<long(*)(double)>(&foo)(d);
like image 194
Dietmar Kühl Avatar answered Sep 18 '22 00:09

Dietmar Kühl