2017-10-09 69 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})''。擴展本身不需要用大括號括起來 - 這些都是初始化程序列表語法的一部分,而不是包擴展語法的一部分。 –

相關問題