我需要实现一个在实例化时接受任何(!)函数指针的仿函数,分析参数类型,存储指针以及何时调用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,但我想不出能达到我想要的方法......
答案 0 :(得分:10)
丢失typedef。采用变量参数的函数是一种特定类型,它与采用类型参数的函数不兼容,并且它不能具有稍后指定的参数类型。
这应该起作用:
template<typename... ARGS> Foo(function<void(*)(ARGS... args)> f);
当然,你真正需要的是对类进行模板化,这样你就可以记住函数需要的参数。
#include <functional>
template<typename... ARGS>
class Foo
{
std::function<void(ARGS...)> m_f;
public:
Foo( std::function<void(ARGS...)> f ) : m_f(f) {}
void operator()(ARGS... args) const { m_f(args...); }
};
template<typename... ARGS>
Foo<ARGS...> MakeFoo(void(*f)(ARGS...)) { return Foo<ARGS...>(f); }
void func1(double *a1, double *a2, double *b)
{ //do something
}
int main(void)
{
auto func1_functor = MakeFoo(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;
}
答案 1 :(得分:3)
为了保持类型安全,Foo
还应编码参数的类型。问题没有完全指定用例,因此我不确定是否需要能够通过无类型的用例。 Foos周围仍然有每个人以某种方式记住(在运行时)它的参数类型是什么。无论如何,这段代码将与qeustion中给出的示例一起使用。
#include<utility>
template<typename FunctionType>
struct Foo {
FunctionType f;
Foo(FunctionType f_) : f(f_) {}
template<typename... Args>
void operator() (Args&&... args) {
f( std::forward<Args>(args)... );
}
};
template<typename FunctionType>
Foo<FunctionType> foo(FunctionType f) {
return Foo<FunctionType>(f);
}
void func1(double *, double *, double *)
{ //do something
}
int main() {
auto x = foo(func1);
double d[3] = {2,3,4};
func1(d, d, d);
x(d, d, d);
}