Generics 具有任何参数列表的函数的泛型函子

Generics 具有任何参数列表的函数的泛型函子,generics,c++11,functor,variadic-functions,variadic-templates,Generics,C++11,Functor,Variadic Functions,Variadic Templates,我需要实现一个functor,它在实例化时接受任何(!)函数指针,分析参数类型,存储指针,在调用操作符()时对指针执行某些操作。最简单的情况是,使用参数调用函数 我尝试将函数指针转换为类似std::function的内容,结果出现错误: error: invalid use of incomplete type ‘struct std::function<void (*)(...)>’ /usr/include/c++/4.6/functional:1572:11: error: d

我需要实现一个functor,它在实例化时接受任何(!)函数指针,分析参数类型,存储指针,在调用操作符()时对指针执行某些操作。最简单的情况是,使用参数调用函数

我尝试将函数指针转换为类似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(*)(...)>’
错误:不完整类型“struct std::function”的使用无效
/usr/include/c++/4.6/functional:1572:11:错误:“struct std::function”的声明
我使用的是GCC4.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;
}
#包括
使用名称空间std;
typedef void(*F_vararg)(…);
福班
{
公众:
模板Foo(函数f);
~Foo(){}
templatevoid运算符()(ARGS…ARGS);
私人:
F_vararg m_F;
};
模板
Foo::Foo(函数f)
{
m_f=f;
}
模板
void Foo::operator()(ARGS…ARGS)
{
m_f(args…);
}
无效函数1(双*a1,双*a2,双*b)
{//做点什么
}
内部主(空)
{
Foo-func1函子((std::function)(func1));
双a1[3]={2,3,4};
双a2[3]={2.2,3.2,4.2};
双b[3]={1.5,2.5,3.5};
func1_函子(a1,a2,b);
返回0;
}
这不是编译。。。如果我不将构造函数声明为模板,而是使用“F_vararg F”作为参数,并相应地调整实例化中的强制转换,它会工作(应该吗?),但我没有机会(?)获得有关我需要的函子构造函数中func1参数的任何信息

我错过什么了吗?还有别的办法吗

提前谢谢你

干杯,Steffen

编辑 哇,太快了!我需要它来推迟函数的执行。函子(或其他类)应该能够决定是否以及何时运行函数。决定它将使用从参数列表中收集的信息


我已经看过std::bind,但是我想不出一种方法来实现我想要的…

失去typedef。接受变量参数的函数是一种特定类型,它与接受类型化参数的函数不兼容,并且不能在以后指定参数类型

这应该起作用:

template<typename... ARGS> Foo(function<void(*)(ARGS... args)> f);
模板Foo(函数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;
}
#包括
模板
福班
{
std::函数m_f;
公众:
Foo(std::function f):m_f(f){}
void运算符()(ARGS…ARGS)常量{m_f(ARGS…;}
};
模板

Foo

为了类型安全,
Foo
还应该对参数的类型进行编码。这个问题没有完全指定用例,所以我不确定是否需要它能够传递“无类型”的foo,并且仍然让每个foo(在运行时)以某种方式记住其参数的类型。无论如何,此代码将与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);
}
#包括
模板
结构Foo{
功能类型f;
Foo(函数类型f_uu):f(f_u){
模板
void运算符()(Args&&…Args){
f(标准:正向(参数)…);
}
};
模板
Foo-Foo(函数类型f){
返回Foo(f);
}
void func1(双精度*,双精度*,双精度*)
{//做点什么
}
int main(){
自动x=foo(func1);
双d[3]={2,3,4};
职能1(d,d,d);
x(d,d,d);
}

typedef void(*F_vararg)(…);-这是一个C风格的vararg函数,对于可变模板,你根本不需要它。你需要它做什么?是的,毕竟还有std::bind。这是目前非常不安全的类型。您希望它进行类型检查以确保参数匹配吗?如果是这样的话,您就不能只使用类型
Foo
。您必须在functor类型中对参数类型进行编码,类似于
Foo
,以表示返回一个void并接受三个double作为参数的functor。@Cat:如果您想在调用函数之前自动记录所有参数,然后记录返回值,该怎么办。当然,您可以为每个函数签名编写一个包装器,也可以尝试编写一个可重用的模板日志包装器。谢谢,这看起来很有希望。但是我如何在main中实例化函子呢?谢谢@Ben!我更正了运算符()定义中的…参数(编译器错误)。仍然有一些编译器错误。。。但我觉得我们越来越近了:)---错误:“Foo::m_f”的类型不完整----错误:调用“Foo::Foo(void(&)(double,double*,double*)”没有匹配的函数----候选函数是:constexpr Foo::Foo(const Foo&)-----@steffen:我发现并修复了这些问题;它正在工作。