I was trying a new approach to the answer I gave to this question, I thought that returning the address of a member function as ID could be a path worth to explore:
struct S
{
template <typename T>
void f(){};
using mp = void(S::*)();
template <typename T>
static constexpr mp ID()
{
return &S::f<T>;
}
};
I thought that every instantiation of S::f
would have an unique address which will be shared in every translation unit and even might be available at compile time, so I tested it:
std::cout << S::ID<char>() << '\n';
And the output was 1
; quite unexpected to be honest (I was expecting the value to be printed as an hex number, like other pointers), but moving forward I tried other types:
std::cout << S::ID<char>() << '\n'; // Prints '1'.
std::cout << S::ID<char>() << '\n'; // Expecting '1', got '1'.
std::cout << S::ID<short>() << '\n'; // Execting something different to '1', got '1'.
At this point, I realized that the 1
value wasn't the "adress of the member function inside the object" because two different functions (void S::f<char>()
and void S::f<short>()
) shared the same address. So I've tried another approach:
struct S
{
template <typename T>
static auto ID()
{
return +[]{};
}
};
Captureless lambdas can be converted to function pointers and each lambda has an unique type even if its contents are the same, so I was expecting some random-ish values but got 1
again:
std::cout << S::ID<char>() << '\n'; // Expecting '0x????????' Prints '1'.
std::cout << S::ID<char>() << '\n'; // Expecting '0x????????' Prints '1'.
std::cout << S::ID<short>() << '\n'; // Expecting '0x!!!!!!!!' Prints '1'.
At this point, I just want to know what those 1
means and why are all of them 1
even if the expected behaviour is that all of them must yield a different value.