C++ is complex. i constantly get surprised by corner cases. few days back Sławek asked me if i know, if return type of a function is a part of a function's signature. i said “no” and he replied “well – i though so too”. it runs out that the correct answer is… “it depends”. let's have a look at some examples:
int f1(int); template<typename T> int f2(int); template<typename T> struct A { template<typename U> int f3(int); }; template<typename T> struct B { int f4(int); }; void foo() { f1(1); f2<double>(2); A<double> a; a.f3<double>(3); B<double> b; b.f4(4); }
now let's see what's the compiler's output:
clang++ -Wall -std=c++14 syms.cpp -c nm syms.o | c++filt | grep U
and we get:
U f1(int) U int f2<double>(int) U int A<double>::f3<double>(int) U B<double>::f4(int)
note that f2 and f3 do have return types in their signatures, while f1 and f4 don't!
as usually – that's the corner case in the C++ spec. looking at C++14 spec 1.3.17 through 1.3.22, explains the secret:
long story short – if you have a template (member) function (partial) (specialization), return type is a part of the signature. otherwise its not.