2010-06-08 3 views
4

Hy,boost :: variant에 대한 반복자

나는 boost :: variant에 기존 코드를 적용하려고합니다. 아이디어는 이종 벡터에 boost :: variant를 사용하는 것입니다. 문제는 나머지 코드가 반복자를 사용하여 벡터 요소에 액세스한다는 것입니다. boost :: variant를 반복자와 함께 사용하는 방법이 있습니까?

나는

typedef boost::variant<Foo, Bar> Variant; 
std::vector<Variant> bag; 
std::vector<Variant>::iterator it; 
for(it= bag.begin(); it != bag.end(); ++it){ 

cout<<(*it)<<endl; 
} 

을 시도했다 그러나 그것은 작동하지 않았다.

편집 : 도움을 주셔서 감사합니다. 그러나 제 디자인에서는 목록에서 하나의 요소를 가져 와서 코드의 다른 부분으로 전달해야합니다 (GSL을 사용함에 따라 불쾌 할 수 있음). 반복기를 사용한다는 생각은 함수에 반복자를 전달할 수 있으며 함수는 해당 특정 요소의 반환 데이터에서 작동합니다. for_each를 사용하는 방법을 알 수 없습니다. 나는 비슷한 것을 할 필요가있다 :

for(it=list.begin(); it!=list.end();++it) { 
    for(it_2=list.begin(); it_2!=list.end();++it_2) { 

    if(it->property() != it_2->property()) { 

     result = operate(it,it_2); 

     } 
    } 

} 

고마워!

답변

8

물론 있습니다. 이터레이터를 참조 해제하면 자연스럽게 boost::variant<...> 참조 또는 const 참조가 생성됩니다.

그러나 나머지 코드는 변형을 인식해야 함을 의미합니다. 특히 변형에 대한 작업을 실행하려면 boost::static_visitor을 사용하십시오.

편집 :

쉬운!

struct Printer: boost::static_visitor<> 
{ 
    template <class T> 
    void operator()(T const& t) const { std::cout << t << std::endl; } 
}; 

std::for_each(bag.begin(), bag.end(), boost::apply_visitor(Printer()); 

방문자가 자동으로 STL 알고리즘 인 miam에 대한 술어를 산출하는 것에 유의하십시오.

자, 반환 값의 문제에 대한 :

class WithReturn: boost::static_visitor<> 
{ 
public: 
    WithReturn(int& result): mResult(result) {} 

    void operator()(Foo const& f) const { mResult += f.suprise(); } 
    void operator()(Bar const& b) const { mResult += b.another(); } 

private: 
    int& mResult; 
}; 


int result; 
std::for_each(bag.begin(), bag.end(), boost::apply_visitor(WithReturn(result))); 

편집 2 :

그것은 쉽지만, 실제로

먼저 코칭 : 약간의 필요, 우리 말 2 가지 조작이 있습니다 : !=operate

struct PropertyCompare: boost::static_visitor<bool> 
{ 
    template <class T, class U> 
    bool operator()(T const& lhs, U const& rhs) 
    { 
    return lhs.property() == rhs.property(); 
    } 
}; 

struct Operate: boost::static_visitor<result_type> 
{ 
    result_type operator()(Foo const& lhs, Foo const& rhs); 
    result_type operator()(Foo const& lhs, Bar const& rhs); 
    result_type operator()(Bar const& lhs, Bar const& rhs); 
    result_type operator()(Bar const& lhs, Foo const& rhs); 
}; 

for(it=list.begin(); it!=list.end();++it) { 
    for(it_2=list.begin(); it_2!=list.end();++it_2) { 

    if(!boost::apply_visitor(PropertyCompare(), *it, *it_2)) { 

     result = boost::apply_visitor(Operate(), *it, *it_2)); 

    } 

    } 
} 

각각 때문에 여기가 좋지 않습니다. if입니다. 비록 당신이 어떻게 든 을 operate에 포함 시키면 작동 할 것입니다.

또한 iterators가 아니라 참조를 전달합니다.

+0

boost :: static_visitor는 요소에서 작동하는 것이 좋지만 클래스가 일부 데이터를 반환해야하는 경우에는 작동하지 않습니다. boost :: ptr_vector >에 대한 반복기를 사용해 보았지만 작동하지 않았다. typedef boost :: variant Variant; std :: vector 가방; std :: vector :: iterator it; for (it = bag.begin(); it! = bag).종료(); ++ it) { cout << (* it) << endl; } – Ivan

+0

항목을 편집하여 용도를 설명합니다. –

+0

고맙습니다. 너무 많이 변경하면서 기존 코드에 개념을 적응 시키려고합니다. 위의 새 편집. – Ivan