如何调用boost multi_index元素的非常量成员函数

我发布这个,因为我无法理解一点提升教程如何工作。

我有一个类,其对象是一个boost multi_index容器的元素。

我需要使用成员函数更新对象的成员variables。 我不知道该怎么做。 请问你能帮帮我吗。 我准备了一个简单的例子:

#include <string> #include <iostream> #include <boost/multi_index_container.hpp> #include <boost/multi_index/member.hpp> #include <boost/multi_index/ordered_index.hpp> #include<vector> using boost::multi_index::multi_index_container; using boost::multi_index::ordered_non_unique; using boost::multi_index::ordered_unique; using boost::multi_index::indexed_by; using boost::multi_index::member; class employee_entry { public: employee_entry( const std::string& first, const std::string& last, long id): first_name_(first), last_name_(last), id_(id) {} void change(){id_++;}//causing the problem std::string first_name_; std::string last_name_; std::vector<int> mySet; long id_; std::vector<int>::iterator mySet_begin() {return mySet.begin(); } }; typedef multi_index_container< employee_entry, indexed_by< ordered_unique<member<employee_entry, std::string, &employee_entry::first_name_> > , ordered_non_unique<member<employee_entry, std::string, &employee_entry::last_name_> > , ordered_non_unique<member<employee_entry, long, &employee_entry::id_> > > > employee_set; //employee set.... multi-index employee_set m_employees; int main() { using boost::multi_index::nth_index; using boost::multi_index::get; typedef nth_index<employee_set, 0>::type first_name_view; first_name_view& fnv = get<0>(m_employees); fnv.insert(employee_entry("John", "Smith", 110)); fnv.insert(employee_entry("Fudge", "Hunk", 97)); ///get employees sorted by id typedef nth_index<employee_set, 2>::type id_view; id_view& idv = get <2> (m_employees); for(id_view::reverse_iterator it = idv.rbegin(), it_end(idv.rend()); it != it_end; ++it) { std::cout << it->first_name_ <<" " << it->last_name_ << ":" << it->id_ << std::endl; it->change();//calling the troublesome function } return 0; } 

产生的错误是:

  $c++ dr_function.cpp dr_function.cpp: In function 'int main()': dr_function.cpp:65:19: error: passing 'const employee_entry' as 'this' argument of 'void employee_entry::change()' discards qualifiers [-fpermissive] 

你发布的解决方案将无法正常工作:最好它会得到一个乱码索引,最糟糕的是你的应用程序将崩溃。 由于你的最后一个索引取决于employee_entry::id_ ,所以你不能自由地改变它,因为你隐式地破坏了索引顺序。 对于这种东西Boost.MultiIndex提供了更新函数replacemodify , 这里讨论。 在您的具体情况下,您可以按如下方式调用您的change成员函数:

 idv.modify(idv.iterator_to(*it),boost::bind(&employee_entry::change,_1)); 

有点解释: idv.iterator_to(*it)只是将你的反向迭代器转换成一个常规的迭代器,这是modify需要。 至于boost::bind部分,它将&employee_entry::change封装到一个合适的修饰函子中。 这样,你让Boost.MultiIndex知道id_即将发生的变化,并相应地更新索引。

好吧,我回答我的问题,至少调试上面提到的代码。 我在这个问题下面的评论中讨论并回答了我的主要关注。 我下面的代码,我做了long id_作为mutable并改变void change(){...} void change()const{...}

 #include <string> #include <iostream> #include <boost/multi_index_container.hpp> #include <boost/multi_index/member.hpp> #include <boost/multi_index/ordered_index.hpp> #include<vector> using boost::multi_index::multi_index_container; using boost::multi_index::ordered_non_unique; using boost::multi_index::ordered_unique; using boost::multi_index::indexed_by; using boost::multi_index::member; class employee_entry { public: employee_entry( const std::string& first, const std::string& last, long id): first_name_(first), last_name_(last), id_(id) {} void change() const {id_++;}//causing the problem std::string first_name_; std::string last_name_; std::vector<int> mySet; mutable long id_; std::vector<int>::iterator mySet_begin() {return mySet.begin(); } }; typedef multi_index_container< employee_entry, indexed_by< ordered_unique<member<employee_entry, std::string, &employee_entry::first_name_> > , ordered_non_unique<member<employee_entry, std::string, &employee_entry::last_name_> > , ordered_non_unique<member<employee_entry, long, &employee_entry::id_> > > > employee_set; //employee set.... multi-index employee_set m_employees; int main() { using boost::multi_index::nth_index; using boost::multi_index::get; typedef nth_index<employee_set, 0>::type first_name_view; first_name_view& fnv = get<0>(m_employees); fnv.insert(employee_entry("John", "Smith", 110)); fnv.insert(employee_entry("Fudge", "Hunk", 97)); ///get employees sorted by id typedef nth_index<employee_set, 2>::type id_view; id_view& idv = get <2> (m_employees); for(id_view::reverse_iterator it = idv.rbegin(), it_end(idv.rend()); it != it_end; ++it) { std::cout << it->first_name_ <<" " << it->last_name_ << ":" << it->id_ << std::endl; it->change();//calling the troublesome function } return 0; }