2011-04-25 4 views
2

나는 boost::bimap<int, boost::shared_ptr<A>> 컨테이너를 가지고 있으며 내용의 일관성을 보장하기 위해 반복기를 왼쪽 뷰로 반환하려고합니다. container.left.begin()을 반환하면 std::pair<int const, boost::shared_ptr<A> const>으로 역 참조하는 반복기가 반환됩니다.shared_ptr 및 boost :: transform_iterator의 boost :: bimap

을 역 참조하여 A을 변경할 수 있으므로 분명히 원하는 것은 아닙니다. std::pair<int const, boost::shared_ptr<A const>> (나는 shared_ptr이 const인지 아닌지는 상관하지 않는다)로 dereferences하는 반복자를 원한다. 나는 아마 boost::transform_iterator을 사용하여 이것을 수행해야한다는 것을 알고 있지만 "캐스팅"기능이 어떻게 보이는지 알아낼 수 없습니다.

아무도 나를 도와 줄 수 있습니까? 아니면 내가 원하는 것을 얻기위한 또 다른 쉬운 방법이 있습니까?

편집 : : 지금까지 내가 뭘했는지는 충분하다고 말하면서, 그것은 2 개의 좋은 화면 오류를 제공합니다.

note: candidate function not viable: no known conversion from 'const boost::bimaps::relation::structured_pair, boost::bimaps::tags::tagged, boost::bimaps::relation::member_at::right>, mpl_::na, boost::bimaps::relation::normal_layout>' to 'const std::pair >' for 1st argument

답변

3

문제는 당신 value_type실제로std::pair (그리고 하나에 암시 적으로 변환되지 않습니다), 따라서 전달 될 수 없다는 것입니다 :

typedef boost::bimap<unsigned int, boost::shared_ptr<A> > container_type; 
typedef container_type::left_const_iterator base_const_iterator; 
typedef boost::transform_iterator<makeIterConst<A>, base_const_iterator> const_iterator; 

template <typename T> 
struct makeIterConst : std::unary_function<std::pair<unsigned int const, boost::shared_ptr<T> const>, std::pair<unsigned int const, boost::shared_ptr<T const> const> > 
{ 
    std::pair<unsigned int const, boost::shared_ptr<T const> const> operator() (std::pair<int const, boost::shared_ptr<T> const> const & orig) const 
    { 
    std::pair<int const, boost::shared_ptr<T const> const> newPair(orig.first, boost::const_pointer_cast<T const>(orig.second)); 
    return newPair; 
    } 
}; 

다음은 "핵심"오류입니다 makeIterConst::operator().

대신 const base_const_iterator::value_type &으로 만듭니다.

#include <iostream> 
#include <string> 
#include <boost/shared_ptr.hpp> 
#include <boost/make_shared.hpp> 
#include <boost/bimap.hpp> 
#include <boost/iterator/transform_iterator.hpp> 

struct A 
{ 
    std::string data; 
    A(const std::string& s) : data(s) {} 
}; 

typedef boost::bimap<unsigned int, boost::shared_ptr<A> > container_type; 
typedef container_type::left_map::const_iterator base_const_iterator; 

template <typename T> 
struct makeIterConst : std::unary_function<base_const_iterator::value_type const &, 
              std::pair<unsigned int const, boost::shared_ptr<T const> const> > 
{ 
    std::pair<unsigned int const, boost::shared_ptr<T const> const> operator() 
      (base_const_iterator::value_type const & orig) const 
    { 
     std::pair<int const, boost::shared_ptr<T const> const> newPair(orig.first, boost::const_pointer_cast<T const>(orig.second)); 
     return newPair; 
    } 
}; 

typedef boost::transform_iterator<makeIterConst<A>, 
           base_const_iterator> const_iterator; 

int main() 
{ 
    container_type m; 
    boost::shared_ptr<A> p = boost::make_shared<A>("foo"); 
    m.insert(container_type::value_type(1, p)); 

// using regular iterator 
    for(base_const_iterator left_iter = m.left.begin(); 
         left_iter != m.left.end(); 
         ++left_iter) 
    { 
     std::cout << left_iter->first << " --> " << left_iter->second->data << '\n'; 
     left_iter->second->data = "bar"; // compiles 
    } 

    // using constified iterator 
    for(const_iterator left_iter = boost::make_transform_iterator(m.left.begin(), makeIterConst<A>()); 
       left_iter != boost::make_transform_iterator(m.left.end(), makeIterConst<A>()); 
      ++left_iter) 
    { 
     std::cout << left_iter->first << " --> " << left_iter->second->data << '\n'; 
// the following will give a compilation error, as expected 
//  left_iter->second->data = "changed_foo"; 
    } 
} 

시험 : https://ideone.com/fHIUe

관련 문제