2011-04-25 111 views
2

我有一個boost::bimap<int, boost::shared_ptr<A>>容器,並希望返回一個迭代器到左視圖,以確保內容的穩定性。返回container.left.begin()返回一個迭代器,該迭代器取消引用std::pair<int const, boost::shared_ptr<A> const>boost :: bimap shared_ptr&boost :: transform_iterator

很明顯,這不是我想要的,因爲可以通過取消引用shared_ptr來更改A。我想要一個迭代器,解除引用std::pair<int const, boost::shared_ptr<A const>>(我真的不在乎shared_ptr是否爲const)。我知道我應該使用boost::transform_iterator來做到這一點,但我無法弄清楚「鑄造」功能應該是什麼樣子。

有人可以幫我解決這個問題嗎?還是有另一種更簡單的方法來獲得我想要的?

編輯:這是我到目前爲止,足以說,它給了我一個良好的2屏幕值得的錯誤。

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; 
    } 
}; 

這裏的「核心」的錯誤:

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(而不是隱式轉換爲一個),因而不能傳遞到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