2017-10-09 60 views
0

我一直在想办法让我的类方法采用任意数量的回调函数,运行所有这些函数,然后存储输出。我认为这是有效的,但有没有一种方法可以做到这一点,我不必让用户将所有的回调函数都包含到向量中?这也只是感觉混乱。随意提及其他不理想的事情。C++类的方法,它采取任意数量的回调和存储结果

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

class MyObj{ 
public: 
    // where I store stuff 
    std::vector<double> myResults; 

    // function that is called intermittently 
    void runFuncs(const std::vector<std::function<double()> >& fs){ 
     if (myResults.size() == 0){ 
      for(auto& f : fs){ 
       myResults.push_back(f()); 
      } 
     }else{ 
      int i (0); 
      for(auto& f : fs){ 
       myResults[i] = f(); 
       i++; 
      } 
     } 
    } 

}; 


int main(int argc, char **argv) 
{ 

    auto lambda1 = [](){ return 1.0;}; 
    auto lambda2 = [](){ return 2.0;}; 

    MyObj myThing; 

    std::vector<std::function<double()> > funcs; 
    funcs.push_back(lambda1); 
    funcs.push_back(lambda2); 
    myThing.runFuncs(funcs); 

    std::cout << myThing.myResults[0] << "\n"; 
    std::cout << myThing.myResults[1] << "\n"; 

    std::vector<std::function<double()> > funcs2; 
    funcs2.push_back(lambda2); 
    funcs2.push_back(lambda1); 
    myThing.runFuncs(funcs2); 

    std::cout << myThing.myResults[0] << "\n"; 
    std::cout << myThing.myResults[1] << "\n"; 


    return 0; 
} 
+0

应该发生什么,如果'runFuncs'被调用了两次,传递更多第二次比第一次回调?目前,在这种情况下,您的程序会显示未定义的行为。 –

+0

我会使用'.empty()'来决定向量是否为空,但我认为将它调整为回调的数量并将结果赋给for循环会更好。我不能保证我看到,如果矢量不是空的,它的尺寸是正确的。 –

+1

这对我来说似乎有点干净。 *耸肩* https://ideone.com/WN697O –

回答

1

事情是这样的,也许:

template <typename... Fs> 
void runFuncs(Fs... fs) { 
    myResults = std::vector<double>({fs()...}); 
} 

然后,你可以把它作为

myThing.runFuncs(lambda1, lambda2); 

Demo

+0

好吧,这看起来很酷。这是一个可变模板,对吧? “{fs()...}”部分发生了什么?我想这只是调用所有的函数,但这叫做什么?为什么它需要用大括号包裹? – Taylor

+1

[参数包扩展](http://en.cppreference.com/w/cpp/language/parameter_pack#Pack_expansion),在大括号初始化列表中。它调用'vector'的构造函数采用'initializer_list',如'std :: vector ({1.0,2.0,3.0})''。扩展本身不需要用大括号括起来 - 这些都是初始化程序列表语法的一部分,而不是包扩展语法的一部分。 –

相关问题