我有一个boost::bimap<int, boost::shared_ptr<A>>
容器,并希望将迭代器返回到左视图,以确保内容的常量。返回container.left.begin()
会返回一个取消引用std::pair<int const, boost::shared_ptr<A> const>
的迭代器。
显然,这不是我想要的,因为可以通过取消引用A
来更改shared_ptr
。我想要一个解除引用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;
}
};
这是“核心”错误:
注意:候选功能不可行: 没有来自'const的已知转换 提高:: bimaps ::关系:: structured_pair, 提高:: bimaps ::标签::标记, 提高:: bimaps ::关系:: member_at ::右&gt;中 MPL _ ::呐, 升压:: bimaps ::关系:: normal_layout&GT;” 到'const std :: pair&gt;'对于 第一个论点
答案 0 :(得分:3)
问题是,您的value_type
不实际上是std::pair
(并且不能隐式转换为1),因此无法传递给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";
}
}