首页 文章

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

提问于
浏览
3

我需要实现一个函数,它在实例化时接受任何(!)函数指针,分析参数类型,存储指针以及何时调用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的参数的任何信息 .

我错过了什么吗?还有另一种方法吗?

先感谢您 !!!

欢呼,斯蒂芬

edit 哇,快点!我需要它来推迟执行功能 . 仿函数(或其他类)应该能够决定是否以及何时运行函数 . 确定它将使用从参数列表中收集的信息 .

我看过std :: bind但是我想不出能达到我想要的方法......

2 回答

  • 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;
    }
    

    演示:http://ideone.com/fnUg2

  • 3

    为了类型安全, Foo 还应该编码参数的类型 . 这个问题不确定是否需要能够传递'typeless' 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);
    }
    

相关问题