template<typename F> class TFunction; template<typename R, typename T0> class TFunction<R(*)(T0)> { };Здесь мы пытаемся специализировать шаблон TFunction для указателя на функцию одного аргумента. Далее имеем два указателя:
typedef bool (*my_function_f)(int); // (1) typedef bool (__stdcall *my_function_f2)(int); // (2)Для (1) специализация, которая написана выше вполне подходит, а вот для (2) — нет. По умолчанию, предполагается что функция использует соглашение вызова __cdecl. Если мы хотим передавать указатели на функции с соглашением вызова __stdcall, то необходимо для этого случая написать отдельную специализацию:
template<typename R, typename T0> class TFunction<R(__stdcall *)(T0)> { };Кажется, этого достаточно. Однако, при компиляции кода под x64 процессоры ключевое слово __stdcall, которое обозначает порядок вызова функций, игнорируется. Обычно это незаметно, но если вы пытаетесь написать частичную специализацию шаблона, то проявляются неприятные эффекты. А именно, две специализации, которые написаны выше, получаются абсолютно одинаковыми, что приводит к ошибке компиляции. Решением будет отключить компиляцию второй специализации, например, так:
#ifndef _M_X64 template<typename R, typename T0> class TFunction<R(__stdcall *)(T0)> { }; #endifМакрос _M_X64 предопределен для x64 процессоров.
Ссылки по теме: