Generic functor for functions with any argument list

后端 未结 2 758
悲哀的现实
悲哀的现实 2020-12-09 06:55

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 some

相关标签:
2条回答
  • 2020-12-09 07:32

    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:

    template<typename... ARGS> Foo(function<void(*)(ARGS... args)> f);
    

    Of course, what you really need is to template the class, so you can remember what arguments the function requires.

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

    Demo: http://ideone.com/fnUg2

    0 讨论(0)
  • 2020-12-09 07:50

    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.

    #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);
    }
    
    0 讨论(0)
提交回复
热议问题