Why C++ function template contains return type in its signature

Viewed 74

For the following code:

template <typename T>
auto fun() { return T{}; }

template <typename T>
T fun2() { return T{}; }

int fun3() { return 0; }

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

int main()
{
    fun<int>();
    fun2<int>();
    fun3();
    fun4(3);
}

When using clang / GCC to compile, the output contains the following function signatures:

$ nm ./a.out | c++filt -t | grep fun
0000000000001206 W auto fun<int>()
0000000000001215 W int fun2<int>()
0000000000001169 T fun3()
0000000000001224 W void fun4<int>(int)

I know that for template function, the return type is included in the signature. However, I don't know why. Are there any usage to dump the return type into the function signature?

Thanks a lot!

1 Answers

Function template overloading can meaningfully depend on the return type:

template<class T> T get_pi() {return 3;}
template<class T>
std::enable_if<std::is_floating_point_v<T>,T> get_pi() {return 3.2;}  // closer

It is of course possible to call the float specialization of the first function template, if only by putting a call to it between the two declarations, so those specializations must have different mangled names.

This is actually true of ordinary functions as well. If you could declare

int f();
void f();

It would be possible to select between them in certain cases:

int x=static_cast<int(*)()>(f)();
void g() {
  void f();  // redeclare the function
  f();
}

However, such tricks notwithstanding, many implementations do omit the return type when mangling a non-template function name, so the standard forbids such overloading (with no diagnostic required if in different translation units).

Related