C ++
我正在尝试通过(函数对象)类(可变参数)模板实现函数包装器。该类具有作为其唯一数据成员的函数指针,该函数指针由其包装的函数指针初始化或分配。参数化构造函数接受函数指针并通过它初始化成员。 operator()
方法接受参数(或无),并用它们调用包装函数。至少这是个主意。我收到很多错误,我用评论标记。 VC11(使用2012年11月的CTP,启用可变参数模板)在除了一个标记区域之外的所有区域中都给出了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
是函数指针类型还是函数类型?如果是后者,那么我可以理解错误消息的上下文。
答案 0 :(得分:2)
您的类由返回值和参数类型参数化,单独拼写。但是在实例化时,您尝试通过函数类型la std::function
对其进行参数化。设为func<int, int, int> myfunc;
。通过此更改,您的代码为works。
答案 1 :(得分:2)
int(int, int)
是一种单一类型。如果你想这样传递它并解开它,你需要部分专业化:
template <typename> struct func; // leave undefined
template <typename R, typename ...Args>
struct func<R(Args...)> // specialized for typename = R(Args...)
{
// ...
};
答案 2 :(得分: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;
}
};