简体   繁体   English

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

[英]Getting a non-const iterator in Boost's multi index container

Using Boost 1_33_1, I get an error implying that my iterator is a const iterator (because it wont let me deref the result from find()). 使用Boost 1_33_1,我得到一个错误,暗示我的迭代器是一个const迭代器(因为它不会让我从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’

I know I am not supposed to modify any of the key values, and I don't, but I still need non-const acces sto modify other data in the container elements. 我知道我不应该修改任何键值,但我没有,但我仍然需要非const访问sto修改容器元素中的其他数据。

I know I have done this successfully elsewhere, I just can't see what would make this const. 我知道我已经在其他地方成功完成了这项工作,我只是看不出是什么会使这个const。

The code below is derived from the original boost::multi_index example 下面的代码源自原始的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++;
}

multi_index doesn't know that you're not going to change members which are the key values. multi_index不知道您不会更改作为关键值的成员。 That's why it's only implements const_iterator. 这就是为什么它只实现const_iterator。

If you want to modify non-key member you can use modify function. 如果要修改非关键成员,可以使用modify功能。 If you're going to change key value you can use modify_key or replace member functions. 如果要更改键值,可以使用modify_keyreplace成员函数。 You can get more info here . 你可以在这里获得更多信息。

multi_index_container<T,...> iterators are immutable, regardless of whether typename T is a class type ( U ) or pointer type ( U* ). multi_index_container<T,...>迭代器是不可变的,无论typename T是类类型( U )还是指针类型( U* )。 The maintainers chose to impose this constraint to safeguard against and emphasize the fact that modifying an element directly (ie, through an iterator) could violate the integrity-constraints of any key-based (associative) indices of the container. 维护者选择强加此约束来防止和强调直接修改元素(即通过迭代器)可能违反容器的任何基于键的(关联)索引的完整性约束这一事实。

For example: An ordered_unique index would be completely invalidated if direct modification of an element (through an iterator) caused the index to no longer be ordered or unique , and the multi_index_container itself would have no knowledge of this change/invalidation (nor would the programmer). 例如:如果元素的直接修改(通过迭代器)导致索引不再被排序唯一 ,并且multi_index_container本身不知道此更改/无效,那么ordered_unique索引将完全无效(程序员也不会)。

Here is a verbatim explanation provided by the maintainers: 以下是维护者提供的逐字解释

By design, index elements are immutable, ie iterators only grant const access to them, and only through the provided updating interface (replace, modify and modify_key) can the elements be modified. 按照设计,索引元素是不可变的,即迭代器只授予对它们的const访问权限,并且只有通过提供的更新接口(replace,modify和modify_key)才能修改元素。 This restriction is set up so that the internal invariants of key-based indices are not broken (for instance, ascending order traversal in ordered indices), but induces important limitations in non key-based indices: 设置此限制是为了不破坏基于键的索引内部不变量 (例如,有序索引中的升序遍历),但在非基于键的索引中会产生重要限制:

Circumventing Const-Correctness 规避正确性

Of course, there are always ways around const-correctness, the most obvious way being const_cast ... but the spirit of C++ is that a programmer should be allowed to do anything he or she wants, even if it's potentially dangerous. 当然,总是存在const-correctness的方法,最明显的方式是const_cast ......但C ++的精神是应该允许程序员做任何他或她想做的事情,即使它有潜在危险。 C++ language/library designers simply do the best they can to discourage such uses. C ++语言/库设计者只是尽其所能阻止这种用法。 And hopefully, when programmers do decide to circumvent those safeguards, it's because they have good reason and know exactly what they're doing. 并且希望,当程序员决定绕过这些保护措施时,这是因为他们有充分的理由并确切地知道他们正在做什么。

I hope this helps. 我希望这有帮助。

From the MultiIndex docs on random access indices : 随机访问索引的MultiIndex文档:

As usual in Boost.MultiIndex, elements of random access indices are immutable and can only be modified through member functions replace and modify. 像往常一样在Boost.MultiIndex中,随机访问索引的元素是不可变的,只能通过成员函数replace和modify来修改。 This precludes the usage of many mutating algorithms that are nonetheless applicable to std::vectors. 这排除了许多变异算法的使用,这些算法仍适用于std :: vectors。

This applies to ordered indexes as well. 这也适用于有序索引

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM