Обертка функции через (класс объекта) шаблон класса (variadic)

C ++

Я пытаюсь реализовать оболочку функции через (класс объекта) шаблон шаблона (variadic). Класс имеет в качестве своего единственного члена данных указатель функции, который инициализируется или присваивается указателю функции, который он переносит. Параметризованный конструктор берет указатель на функцию и инициализирует им член. operator() Метод принимает аргумент (ы) (или ничего) и вызывает с ними упакованную функцию. По крайней мере, это идея. Я получаю много ошибок, которые отмечаю комментариями. VC11 (с CTP в ноябре 2012 года, чтобы включить вариадические шаблоны) дает мне error C2091: function returns function во всех, кроме одной из отмеченных областей. Последняя ошибка отличается, и я комментирую ее полное описание в коде. G ++ дает в основном одни и те же ошибки, хотя и с разными кодовыми номерами.

#include <iostream>

template <typename R, typename... Tn>
class func
{
R (*fptr)(Tn...); // C2091
public:
func() : fptr(nullptr) {}
func( R (*f) (Tn...) ) : fptr(f) {} // C2091
R operator()(Tn... args)
{ // C2091
return fptr(args...);
}
func& operator=( R (*f) (Tn...) ) // C2091
{
fptr = f;
return *this;
}
};

int foo(int a, int b)
{
std::cout << "foo\n";
return 0;
}

int main()
{
func<int(int, int)> myfunc;
myfunc = foo; // C2679: binary '=' : no operator found which takes
// a right-hand operand of type 'int (__cdecl *)(int,int)' (or
// there is no acceptable conversion)
}

Почему я получаю эти ошибки? Например, я не вижу, как параметризованный конструктор возвращает что-либо, или как объявление члена данных возвращает что-либо. Разве декларация члена данных не является формой объявления указателя функции? Например, не int (*g)(int); объявить указатель, который указывает на функцию, которая принимает int и возвращает int?

Редактировать / Добавление:

Я вижу из ответов, что int(int, int) это только один тип, и мне нужна частичная специализация, чтобы получить желаемый эффект. Но что вызывает ошибку в моем коде? Если я закомментирую myfunc = fooЯ все еще получаю другие ошибки. func<int(int, int)> myfunc; вызывает конструктор по умолчанию typename R инстанцируется int(int, int), а также typename... Tn становится пустым. Член данных R (*fptr)(Tn...); становится R (*fptr)();, а также fptr поэтому является указателем на функцию, которая указывает на функцию, которая принимает нулевые аргументы и возвращает R, Если R является int(int, int)то есть R тип указателя на функцию или тип функции? Если это последнее, то я могу понять контекст сообщения об ошибке.

1

Решение

int(int, int) это один единственный тип. Если вы хотите передать это так и развернуть, вам нужна частичная специализация:

template <typename> struct func;         // leave undefined

template <typename R, typename ...Args>
struct func<R(Args...)>                  // specialized for typename = R(Args...)
{
// ...
};
2

Другие решения

Ваш класс параметризован возвращаемым значением и типами аргументов, прописанными отдельно. Но при создании экземпляра вы пытаетесь параметризовать его по типу функции, а std::function, Сделай это func<int, int, int> myfunc;, С этим изменением ваш код работает.

2

Вам нужна частичная специализация.

Вот рабочий пример:

template <typename T>
class func;

template <typename R, typename... Tn>
class func<R(Tn...)> {
typedef R (*fptr_t)(Tn...);
fptr_t fptr;
public:
func() : fptr(nullptr) {}
func(fptr_t f) : fptr(f) {}
R operator()(Tn... args) {
return fptr(args...);
}
func& operator=(fptr_t f) {
fptr = f;
return *this;
}
};
2
По вопросам рекламы [email protected]