2011-05-03 2 views
7

일부 데이터가 포함 된 클래스가 있고 데이터 ID를 통해 반복자를 제공하는 begin()end() 함수를 추가하고 싶습니다. 내가 부스트 counting_iterator 사용하고BOOST_FOREACH에서는 사용자 정의 iterator가 작동하지 않습니까?

:

#include <iostream> 
#include <vector> 
#include <boost/foreach.hpp> 
#include <boost/iterator/counting_iterator.hpp> 

template<class T> 
class ContainerTpl { 
public: 
    typedef std::size_t Id; 
    typedef boost::counting_iterator<Id> const_iterator; 
    ContainerTpl() {} 
    const_iterator begin() { 
    return boost::counting_iterator<Id>(0); 
    } 
    const_iterator end() { 
    return boost::counting_iterator<Id>(container_.size()); 
    } 
private: 
    std::vector<T> container_; 
}; 

int main() { 
    typedef ContainerTpl<double> Container; 
    Container c; 
    BOOST_FOREACH (Container::Id cid, c) { 
    std::cerr << cid << std::endl; 
    } 
    return 0; 
} 

이 최소한의 예제 코드이므로주의 해주십시오을; 실제로 클래스에는 더 많은 기능이 포함되어 있으므로 예를 들어 typedef에서 vector까지는 충분하지 않습니다. ID에 대한 반복자를 사용하여 클래스가 실제로 필요합니다.

In file included from boost/foreach.hpp:71, 
       from a.cpp:3: 
boost/mpl/eval_if.hpp: In instantiation of ‘boost::mpl::eval_if<mpl_::bool_<false>, boost::range_const_iterator<ContainerTpl<double> >, boost::range_mutable_iterator<ContainerTpl<double> > >’: 
boost/foreach.hpp:355: instantiated from ‘boost::foreach_detail_::foreach_iterator<ContainerTpl<double>, mpl_::bool_<false> >’ 
a.cpp:25: instantiated from here 
boost/mpl/eval_if.hpp:38: error: no type named ‘type’ in ‘struct boost::range_mutable_iterator<ContainerTpl<double> >’ 
a.cpp: In function ‘int main()’: 
a.cpp:25: error: no matching function for call to ‘begin(const boost::foreach_detail_::auto_any_base&, boost::foreach_detail_::type2type<ContainerTpl<double>, mpl_::bool_<false> >*, boost::mpl::o\ 
r_<boost::mpl::and_<boost::mpl::not_<boost::is_array<ContainerTpl<double> > >, mpl_::bool_<false>, mpl_::bool_<true>, mpl_::bool_<true>, mpl_::bool_<true> >, boost::mpl::and_<boost::mpl::not_<boo\ 
st::foreach::is_noncopyable<ContainerTpl<double> > >, boost::foreach::is_lightweight_proxy<ContainerTpl<double> >, mpl_::bool_<true>, mpl_::bool_<true>, mpl_::bool_<true> >, mpl_::bool_<false>, m\ 
pl_::bool_<false>, mpl_::bool_<false> >*)’ 
a.cpp:25: error: no matching function for call to ‘end(const boost::foreach_detail_::auto_any_base&, boost::foreach_detail_::type2type<ContainerTpl<double>, mpl_::bool_<false> >*, boost::mpl::or_\ 
<boost::mpl::and_<boost::mpl::not_<boost::is_array<ContainerTpl<double> > >, mpl_::bool_<false>, mpl_::bool_<true>, mpl_::bool_<true>, mpl_::bool_<true> >, boost::mpl::and_<boost::mpl::not_<boost\ 
::foreach::is_noncopyable<ContainerTpl<double> > >, boost::foreach::is_lightweight_proxy<ContainerTpl<double> >, mpl_::bool_<true>, mpl_::bool_<true>, mpl_::bool_<true> >, mpl_::bool_<false>, mpl\ 
_::bool_<false>, mpl_::bool_<false> >*)’ 
a.cpp:25: error: no matching function for call to ‘deref(const boost::foreach_detail_::auto_any_base&, boost::foreach_detail_::type2type<ContainerTpl<double>, mpl_::bool_<false> >*)’ 

가 어떻게 코드 작업을 할 수 있습니다 :

불행하게도, 위의 코드는 나에게 매우 불쾌한 컴파일러 오류를 준다?

UPDATE :

namespace boost 
{ 
// specialize range_mutable_iterator and range_const_iterator in                                  
// namespace boost                                             
template<class T> 
struct range_mutable_iterator< ContainerTpl<T> > { 
    typedef typename ContainerTpl<T>::const_iterator type; 
}; 

template<class T> 
struct range_const_iterator< ContainerTpl<T> > { 
    typedef typename ContainerTpl<T>::const_iterator type; 
}; 
} // end namespace   

답변

8

그것에 대해 부스트 문서의 페이지있다 : 대답에 따라, 나는 그것이 작동하게 다음 코드를 추가, 즉

http://boost-sandbox.sourceforge.net/libs/foreach/doc/html/foreach/extensibility.html

당신 컴파일러가 BOOST_FOREACH이 사용하려고하는 템플릿 유형을 인스턴스화 할 수 있도록 유형에 boost::range_mutable_iterator<>을 정의해야합니다. 향후 Google 직원

편집 :

는 그 "샌드 박스"URL을 항상 최신 버전을 가리거나 결국 중단하는 과도 위치합니다 있는지 확실하지 않습니다.

http://www.boost.org/doc/libs/1_50_0/doc/html/foreach/extensibility.html

2

을 나는이 오래된 질문 알아요,하지만 여전히 관련 같다 : 이것은 오래 될 것이지만, 더 안정 될 수있는 현재 버전에 대한 링크입니다. 이 문제가 있었고 foreach가 booster에 반복 가능한 iterator와 const_iterator (ContainerTpl :: iterator와 ContainerTpl :: const_iterator)가 정의되어 있어야합니다. Tim이 제공 한 지시 사항을 따라야하는 경우 실패합니다.

+0

이것은 이것이 작동하는 데 필수적입니다. 필자의 경우'typedef iterator const_iterator'는 충분했지만 거기에 있어야합니다. 그렇지 않으면 암시 적 컴파일러 오류가 발생합니다. / – Patryk

관련 문제