Каковы правила создания экземпляров типов шаблонов (класса / функции) при получении адреса?

Отвечая на этот вопрос, я обнаружил эту разницу в поведении относительно создания экземпляра шаблона.

Первоначально существует шаблон функции

template  void my_callback(void* data) { … }

Теперь что-то требует адреса этого - а именно void * , поэтому очевидный подход -

bar(reinterpret_cast(&my_callback));

. Однако с версиями компилятора до gcc 4.5 это не удается из-за недостаточного контекста ... ошибка. Отлично - поэтому исправление состоит в том, чтобы сначала "выполнить приведение" - что вызывает создание экземпляра, то есть:

void (*callback)(void*) = my_callback;
bar(reinterpret_cast(callback));

Это работает нормально.

Теперь второй сценарий, вместо того, чтобы быть свободной функцией, он является статическим членом шаблон класса, т.е.

template 
struct foo
{
  static void my_callback(void* data) {
    T& x = *static_cast(data);
    std:: cout << "Call[T] with " << x << std::endl;
  }
};

Теперь исходный reinterpret_cast работает нормально.

bar(reinterpret_cast(&foo::my_callback));

Итак, мой вопрос - почему эта очевидная разница в поведении?

6
задан Community 23 May 2017 в 12:18
поделиться