2017-10-09 1 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

로 호출 할 수 있습니다 콜백은 처음보다 두 번째입니까? 이 경우 프로그램은 정의되지 않은 동작을 보입니다. –

+0

'.empty()'를 사용하여 벡터가 비 었는지 여부를 결정할 수 있지만 콜백 수만큼 크기를 조정 한 다음 결과를 for 루프에 할당하는 것이 더 좋을 것이라고 생각합니다. 벡터가 비어 있지 않으면 올바른 크기라는 것을 알 수는 없습니다. –

+1

이것은 나에게 조금 더 깨끗해 보인다. * 으스스한 * https://ideone.com/WN697O –

답변

1

뭔가 : runFuncs`가 두 번 호출되는`경우

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

그런 다음 당신이 더 전달

myThing.runFuncs(lambda1, lambda2); 
어떻게해야합니까

Demo

+0

괜찮아 보이는이. 그것은 variadic 템플릿 맞죠? '{fs() ...}'부분은 어떻게됩니까? 그냥 모든 기능을 호출하는 것 같지만,이 기능은 무엇입니까? 왜 중괄호로 묶어야합니까? – Taylor

+1

[매개 변수 팩 확장] (http://en.cppreference.com/w/cpp/language/parameter_pack#Pack_expansion)을 중괄호 목록에 추가하십시오. 그것은'std :: vector ({1.0, 2.0, 3.0})'에서와 같이'initializer_list'를 취하는'vector'의 생성자를 호출합니다. 확장 자체는 중괄호로 묶을 필요가 없습니다. 이는 팩 확장 구문이 아닌 초기화 프로그램 목록 구문의 일부입니다. –

관련 문제