制作一个复合std::函数

Making a composite std::function

本文关键字:复合 std 一个 函数      更新时间:2023-10-16

我创建了这个函数Functions,它用于存储多个std::functions,并按顺序调用它们,就好像它本身就是std::function一样:

typedef std::function <void (int)> FuncType;
struct Functions
{
    vector<FuncType> m;
    void operator+= (FuncType f) { 
        m.push_back(f);
    }
    void operator() (int param ){  // same prototype as FuncType
        vector<FuncType>::iterator it;
        for(it=m.begin(); it!=m.end(); ++it) {
            (*it)(param);
        }
    }
};

它非常有用,因为它可以存储在FuncType:中

int main()
{
    Functions f;
    f += foo;
    f += bar;
    FuncType ptr(f);
    ptr(10);  // calls foo(10), then bar(10)
}

它工作得很好,但我希望能够使它成为一个模板化的函子。但我想不出一种方法来让operator()遵循功能的原型:

template <typename FuncType>    // for any Function type
struct Functions
{
    vector<FuncType> m;
    void operator+= (FuncType f) { 
        m.push_back(f);
    }
    void operator() (...) {  // how do I get the same prototype as FuncType?
        vector<FuncType>::iterator it;
        for(it=m.begin(); it!=m.end(); ++it) {
            (*it)(...);
        }
    }
};

理想情况下,我还希望有一个辅助函数,它实例化函子(当然,前提是所有函数都有相同的原型),如下所示:

template <typename T>
Functions<T> make_functions( T funcA, T funcB ) {
    Functions<T> f;
    f += funcA;
    f += funcB;
    return f;
}

但我不确定编译器是否能够推断出T是std::函数<>某种

我正在使用std::tr1

template<typename Sig> struct Functions;
template<typename R, typename... Args>
struct Functions<R(Args...)>{
  typedef std::function<R(Args...)> FuncType;
  std::vector<FuncType> fs;
  void operator+=(FuncType f){fs.emplace_back(std::move(f));}
  template<typename...Us>
  void operator()(Us&&...us){
    for(auto&&f:fs)
      f(us...);
  }
};
int main(){
  Functions<void(int)> funcs;
  funcs += [](int x){ std::cout<<x<<"n";};
  funcs(7);
}

真正完美的转发和收集作为练习留下的回报值。

这样的东西怎么样?编辑:正如所指出的,我错过了make_function,也错过了与std::forward完美地进行辩论的机会。http://coliru.stacked-crooked.com/a/f597aacd3b7ce404

#include <functional>
#include <iostream>
#include <vector>

template<typename T, typename... Args>
class Functions
{
    private:
        std::vector<std::function<T(Args...)>> vec;
    public:
        void operator += (std::function<T(Args...)> f)
        {
            vec.push_back(f);
        }
        void operator()(Args... args)
        {
            for (auto &f : vec)
            {
                f(std::forward<Args>(args)...);
            }
        }
};
int main()
{
    Functions<void> funcs;
    funcs += []{std::cout<<"Foon";};
    funcs += []{std::cout<<"Barn";};
    funcs();
    std::cout<<"n";
    Functions<void, int> funcs2;
    funcs2 += [](int a){std::cout<<"Foo"<<a<<"n";};
    funcs2 += [](int b){std::cout<<"Bar"<<b<<"n";};
    funcs2(2);
}