STL

2015-02-06 3 views
5

동적 펑 전달 나는 C 비교적 새로운 오전 ++이, 그래서STL

내가 많은 STL과 기능이 요구하는 것처럼, 함수 포인터 또는 함수 객체를 전달하는 방법을 이해 ;-) 부드럽게 내 첫 번째 게시물입니다. 이걸 상속과 함께 사용하는 방법은 나에게는 불분명하다.

특히 저는 기본 펑터를 상속받은 여러 펑터가있는 stl 함수를 호출하고 싶습니다. 이 주제에 대한 관련 발언이나 우수 사례를 찾지 못했습니다. 여기서 단순 코드 :이 제공 컴파일

struct generator{ 
    virtual int operator()() = 0; 
    virtual ~generator(){}; 
}; 

struct A : public generator{ 
    int operator()(); 
}; 

struct B : public generator{ 
    int operator()(); 
}; 

int main() 
{ 
    auto v = std::vector<std::array<int, 500>>(2); 
    std::array<std::shared_ptr<generator>, 2> functors = {{std::make_shared<A>(), 
                 std::make_shared<B>()}}; 
    for (size_t i = 0; i < functors.size(); ++i) 
    std::generate(std::begin(v[i]), std::end(v[i]), 
        *(functors[i])); 
    return 0; 
} 

:

clang++ -std=c++11 -g -Wall -Wextra test_stackoverflow.cpp 
test_stackoverflow.cpp:25:5: error: no matching function for call to 'generate' 
    std::generate(std::begin(v[i]), std::end(v[i]),*(functors[i])); 
    ^~~~~~~~~~~~~ 
/usr/lib/gcc/i686-linux-gnu/4.6/../../../../include/c++/4.6/bits/stl_algo.h:5003:5: note: candidate template ignored: substitution 
     failure [with _ForwardIterator = int *, _Generator = generator]: parameter type 'generator' is an abstract class 
    generate(_ForwardIterator __first, _ForwardIterator __last, 

예 *의 종류 ([I] 펑) 발생기

이다. A :: operator() 및 B :: operator()에 대한 동적 액세스를 허용하지 않습니다. 나는 이것을 (우발적으로) 풀 수있는 방법을 이해한다. 예 :

std::generate(std::begin(v[i]), std::end(v[i], 
       [&]{ return functors[i]->operator()(); }; 

그러나 다소 혼란스러워 보이지만 목표를 달성하기위한 더 명확한 방법을 찾고 있습니다.

일반적으로 이러한 동적 펑터를 어떻게 통과합니까? 또는 이것에 눈살을 찌푸린 경우에, 제일 대안은 무엇입니까?

모든 도움이나 제안을 환영합니다.

답변

1

이미 알고있는 것처럼 문제는 std::generate이 값으로 생성기를 사용한다는 것입니다. 다형성 객체를 전달하려면 참조로 전달해야합니다.

그리고 C++ 11에서 이런 종류의 문제에 대한 해결책이 있습니다 (람다 옵션 외에도 C++ 11 이전에 비해 훨씬 더 우아합니다). 해결책은 std::ref입니다. 값으로 전달할 수있는 참조 래퍼를 반환합니다. 당신이 펑터로 참조 래퍼를 전달할 수있는 이유,

std::generate(std::begin(v[i]), std::end(v[i]), 
       std::ref(*(functors[i]))); 

이유를`, 그들은 또한 operator()

+0

를 구현하는 것이, 할 수있는 확인 된 표준 : function' –

+0

입니다 :

이 당신을 위해 일한다 'std :: ref'를 알고리즘에 전달하십시오. 그걸 몰랐어. http://coliru.stacked-crooked.com/a/db815184c44240ad –

+0

나는 정직 할 것이다. 나는 std :: ref에 대해 들어 본 적이 없다. 고맙습니다. 람다가 이걸 선호하는 의견이 있습니까? 그렇다면 왜 그렇습니까? – APevar