Указатель на функцию-член, всегда печатается как "1"
Я пытался по-новому взглянуть на ответ, который дал на этот вопрос, и подумал, что возвращение адреса функции-члена в качестве идентификатора может быть полезным путем:
struct S
{
template <typename T>
void f(){};
using mp = void(S::*)();
template <typename T>
static constexpr mp ID()
{
return &S::f<T>;
}
};
Я думал, что каждый экземпляр S::f
будет иметь уникальный адрес, который будет использоваться в каждом модуле перевода и даже может быть доступен во время компиляции, поэтому я проверил его:
std::cout << S::ID<char>() << '\n';
И выход был 1
; честно говоря, довольно неожиданно (я ожидал, что значение будет напечатано в виде шестнадцатеричного числа, как и другие указатели), но двигаясь вперед, я попробовал другие типы:
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'.
В этот момент я понял, что 1
значение не было " адресом функции-члена внутри объекта ", потому что две разные функции (void S::f<char>()
а также void S::f<short>()
) поделился тем же адресом. Поэтому я попробовал другой подход:
struct S
{
template <typename T>
static auto ID()
{
return +[]{};
}
};
Лямбды без захвата могут быть преобразованы в указатели на функции, и каждая лямбда имеет уникальный тип, даже если ее содержимое одинаково, поэтому я ожидал некоторые случайные значения, но получил 1
снова:
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'.
На данный момент, я просто хочу знать, что эти 1
значит и почему они все 1
даже если ожидаемое поведение таково, что все они должны давать различное значение.