具有任何参数列表的函数的通用仿函数
我需要实现一个函子,它在实例化时接受任何(!)函数指针,分析参数类型,存储指针,并在调用operator()时对指针执行某些操作。最简单的情况是,使用其参数调用函数。
我尝试将函数指针转换为 std::function 之类的内容,但收到错误:
error: invalid use of incomplete type ‘struct std::function<void (*)(...)>’
/usr/include/c++/4.6/functional:1572:11: error: declaration of ‘struct std::function<void(*)(...)>’
我正在使用 gcc 4.6.1,使用 -std=c++0x 进行编译
这是一个最小的示例:
#include <functional>
using namespace std;
typedef void (*F_vararg)(...);
class Foo
{
public:
template<typename... ARGS> Foo(function<F_vararg(ARGS... args)> f);
~Foo(){}
template<typename... ARGS>void operator()(ARGS... args);
private:
F_vararg m_f;
};
template<typename... ARGS>
Foo::Foo(function<F_vararg(ARGS... args)> f)
{
m_f = f;
}
template<typename... ARGS>
void Foo::operator()(ARGS... args)
{
m_f(args...);
}
void func1(double *a1, double *a2, double *b)
{ //do something
}
int main(void)
{
Foo func1_functor((std::function<void (*)(...)>)(func1));
double a1[3] = {2.,3.,4.};
double a2[3] = {2.2,3.2,4.2};
double b[3] = {1.5,2.5,3.5};
func1_functor(a1,a2,b);
return 0;
}
这不会编译... 如果我没有将构造函数声明为模板,而是使用“F_vararg f”作为参数,并相应地调整实例化中的转换,它可以工作(应该吗?),但我没有机会(?)获得有关func1 的参数我需要的函子的构造函数。
我错过了什么吗?还有其他方法可以做到这一点吗?
先感谢您 !!!
干杯,史蒂芬
编辑 哇,太快了!我需要它来推迟函数的执行。函子(或另一个类)应该能够决定是否以及何时运行函数。决定它将使用从参数列表中收集的信息。
我看过 std::bind 但我想不出一种方法来实现我想要的......
I need to implement a functor that takes any (!) function pointer when instantiated, analyses the argument types, stores the pointer and when operator() is called, does something with the pointer. The easiest case being, calling the function with its arguments.
I tried converting the function pointer to something like std::function and I get the error:
error: invalid use of incomplete type ‘struct std::function<void (*)(...)>’
/usr/include/c++/4.6/functional:1572:11: error: declaration of ‘struct std::function<void(*)(...)>’
I am using gcc 4.6.1, compiling with -std=c++0x
This is a minimal example:
#include <functional>
using namespace std;
typedef void (*F_vararg)(...);
class Foo
{
public:
template<typename... ARGS> Foo(function<F_vararg(ARGS... args)> f);
~Foo(){}
template<typename... ARGS>void operator()(ARGS... args);
private:
F_vararg m_f;
};
template<typename... ARGS>
Foo::Foo(function<F_vararg(ARGS... args)> f)
{
m_f = f;
}
template<typename... ARGS>
void Foo::operator()(ARGS... args)
{
m_f(args...);
}
void func1(double *a1, double *a2, double *b)
{ //do something
}
int main(void)
{
Foo func1_functor((std::function<void (*)(...)>)(func1));
double a1[3] = {2.,3.,4.};
double a2[3] = {2.2,3.2,4.2};
double b[3] = {1.5,2.5,3.5};
func1_functor(a1,a2,b);
return 0;
}
This does NOT compile... If I don't declare the constructor as a template but with "F_vararg f" as the argument, and adjust the cast in the instantiation accordingly, it works (should it?) but I have no chance (?) of getting any information on the arguments of func1 in the constructor of the functor which I need.
Am I missing something? Is there another way to do that?
Thank you in advance !!!
cheers, Steffen
edit
Wow, that was quick! I need that for postponing the execution of functions. The functor (or another class) should be able to decide whether and when to run a function. To decide that it will use the information gathered from the argument list.
I have looked at std::bind but I couldn't think of a way to achieve what I want...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
丢失 typedef。采用可变参数的函数是特定类型,它与采用类型化参数的函数不兼容,并且不能在以后指定参数类型。
这应该可行:
当然,您真正需要的是模板化类,这样您就可以记住函数需要哪些参数。
演示:http://ideone.com/fnUg2
Lose the typedef. A function that takes variable arguments is a specific type, it's not compatible with functions taking typed arguments, and it can't have parameter types specified later.
This should work instead:
Of course, what you really need is to template the class, so you can remember what arguments the function requires.
Demo: http://ideone.com/fnUg2
为了实现类型安全,
Foo
还应该对参数的类型进行编码。这个问题没有完全指定用例,所以我不确定是否需要能够传递“无类型”Foos,并且仍然让每个人以某种方式记住(在运行时)其参数的类型是什么。无论如何,这段代码将与问题中给出的示例一起使用。To be type-safe,
Foo
should also encode the type of the arguments. The question doesn't specify the use-case fully, so I'm not sure if it is required to be able to pass 'typeless' Foos around and still have each one somehow remember (at runtime) what the types of its arguments are. Anyway, this code will work with the example given in the qeustion.