2013-06-26 3 views
0

Я пытаюсь специализировать шаблон класса объявлен как таковой:Специализируется класс для общей функции, возвращающей указатель на функцию

template<typename T> class A; 

для функции, возвращающей указатель на функцию. Это должно быть общей сигнатурой для любой заданной ясности функции.

Таким образом, если предположить, что я знаю, как C/C++ синтаксис работы, специализация должна выглядеть примерно так на функцию, возвращающую некоторый тип ResultType:

template<typename ResultType, typename Arg1, typename Arg2> 
A<ResultType(Arg1, Arg2)> {...}; 

И расширяется, что к тому ResultType быть указатель на функцию должен что-то вроде этого:

template<typename FpResultType, typename FpArg1, typename Arg1, typename Arg2> 
A<(ResultType(*)(FpArg1))(Arg1, Arg2)> {...}; 

Это, однако, приводит к «недопустимому параметру шаблона» в GCC 4.6.

Насколько я знаю, typedefs здесь нет. Добавление класса утилиты для создания typedef для меня также является необязательным, поскольку оно перемещает типы из списка типов имен в объявлении шаблона в другой тип шаблона и «скрывает» их от специализации шаблона A (что приводит к компиляции, что объявленные имена не используются в специализации).

Я бы предпочел избежать длинной сложной цепочки enable_ifs и структур утилит. Но, если это единственный способ сделать это, meh.

+0

Какова подпись указателя функции, которую вы хотите вернуть? – jrok

ответ

2

Я считаю, что это будет работать, если вы специализируетесь как:

template<typename FpResultType, typename FpArg1, typename Arg1, typename Arg2> 
A<ResultType (*(Arg1, Arg2))(FpArg1)> {...}; 

Я проверил с помощью следующего кода, который компилирует успешно (с использованием Clang):

template<typename T> class A; 

template<typename FnRetT, typename FnArgT, typename Arg1, typename Arg2> 
class A<FnRetT (*(Arg1, Arg2))(FnArgT)> 
{ 
public: 
    typedef FnRetT fn_ret_t; 
}; 

float foo(float a) 
{ 
    return a; 
} 

float (*getfn(int arg1, int arg2))(float) 
{ 
    return foo; 
} 

int main(int argc, const char * argv[]) 
{ 
    typedef A<decltype(getfn)>::fn_ret_t ret_ty; 

    return 0; 
} 

Обратите внимание, что синтаксис, используемый для соответствие типа функции соответствует объявлению getfn.

+0

Много gracias senor. Пусть испанская инквизиция не попытается заставить меня зарезать свой язык в этом комментарии и злоупотреблять шаблонами с помощью приведенных здесь инструментов. – user