在Boost的多索引容器中获取非const迭代器

时间:2011-10-26 19:18:32

标签: c++ boost

使用Boost 1_33_1,我得到一个错误,暗示我的迭代器是一个常量迭代器(因为它不会让我从find()中解析结果。)

$ g++ bmi_iter_tst.cpp 
bmi_iter_tst.cpp: In function ‘void tst(employee_set&)’:
bmi_iter_tst.cpp:32: error: invalid initialization of reference of type ‘employee&’ from expression of type ‘const employee’

我知道我不应该修改任何键值,但我没有,但我仍然需要非const访问sto修改容器元素中的其他数据。

我知道我已经在其他地方成功完成了这项工作,我只是看不出会使这个const成为什么。

以下代码源自原始boost::multi_index示例

#include <boost/multi_index_container.hpp>
#include <boost/multi_index/member.hpp>
#include <boost/multi_index/ordered_index.hpp>


using boost::multi_index_container;
using namespace boost::multi_index;

struct employee
{
  int         id;
  int         tst;

  employee(int id_):id(id_), tst(0){}
};


struct id{};


typedef multi_index_container<
  employee,
  indexed_by<
    ordered_unique<
      tag<id>,  BOOST_MULTI_INDEX_MEMBER(employee,int,id)> >
> employee_set;


void tst(employee_set& s)
{
  employee_set::index_iterator<id>::type it = s.get<id>().find(11);
  employee& eref = *it;

  eref.tst++;
}

3 个答案:

答案 0 :(得分:10)

multi_index并不知道您不会更改作为关键值的成员。这就是为什么它只实现了const_iterator。

如果要修改非关键成员,可以使用modify功能。如果您要更改键值,可以使用modify_keyreplace成员函数。您可以获得更多信息here

答案 1 :(得分:4)

来自random access indices上的MultiIndex文档:

  

与Boost.MultiIndex中一样,随机访问索引的元素是   不可变,只能通过成员函数replace来修改   并修改。这排除了许多变异算法的使用   尽管如此,它仍然适用于std :: vectors。

这也适用于ordered indexes

答案 2 :(得分:4)

无论typename multi_index_container<T,...>是类类型(T)还是指针类型(U),

U*迭代器都是不可变的。维护者选择强加这种约束来防止并强调直接修改元素(即通过迭代器)可能违反容器的任何基于密钥(关联)索引的完整性约束这一事实。

例如:如果直接修改元素(通过迭代器)导致索引不再有序,则ordered_unique索引将完全失效或唯一multi_index_container本身不知道此更改/失效(程序员也不会)。

这是维护者提供的verbatim explanation

  

按照设计,索引元素是不可变的,即迭代器只授予   const访问它们,并且只能通过提供的更新界面   (替换,修改和修改_key)可以修改元素。这个   设置限制,以便基于键的内部不变量   索引不会被破坏(例如,升序顺序遍历)   有序指数),但在非基于密钥的情况下引起了重要的限制   指数:

规避正确性

当然,总是存在const-correctness的方法,最明显的方式是const_cast ......但C ++的精神是程序员应该允许做任何事情他或她想要,即使它有潜在危险。 C ++语言/库设计者只是尽其所能阻止这种用法。并且希望,当程序员决定绕过这些保护措施时,这是因为他们有充分的理由并且知道完全他们正在做什么。

我希望这会有所帮助。