2015-02-23 35 views
0
#include "modify_example.hpp" 

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

#include <iostream> 
#include <string> 

using namespace boost::multi_index; 

namespace{ 

struct name{}; 
struct email{}; 

struct employee 
{ 
    std::string email_; 
    std::string name_; 

    employee(std::string name, std::string email) : 
     email_(email), 
     name_(name) 
    {} 
}; 

using DispatchUsersTable = 
multi_index_container 
< 
    employee, 
    indexed_by 
    < 
    ordered_unique 
    < 
     tag<name>, member 
     <employee, std::string, &employee::name_> 
    >, 
    ordered_unique 
    < 
     tag<email>, member 
     <employee, std::string, &employee::email_> 
    > 
    > 
>; 

} 

void order_after_modify() 
{ 
    DispatchUsersTable table; 
    table.insert(employee{"jk", "http:cat"}); 
    table.insert(employee{"otaku", "http:joker"}); 
    table.insert(employee{"cba", "http:amota"}); 

    //auto will make codes much easier to read 
    //I type the type explicitly because I need to 
    //maintain the codes created by c++98 
    using Table = DispatchUsersTable::index<name>::type; 
    using Iterator = Table::iterator; 

    std::vector<std::string> names{"doremi", "onpu", "aichan"}; 
    size_t num = 0; 
    for(Iterator it = table.get<name>().begin(); 
     it != table.get<name>().end();){ 
     std::cout<<it->name_<<", "<<it->email_<<std::endl; 
     name_index.modify(it++, [&](employee &e){ e.name_ = names[num++]; }); 
    }    
} 

我想通过for循环 修改所有的multi_index的内容,但该代码不能正常工作(随机行为),我想我不明白当我将修改操作和迭代结合在一起时,正确的迭代器。什么是正确的方法来做到这一点?迭代和修改的boost ::多指标的数据

+2

我觉得非常讽刺的是,你对此有何评论_'I明确键入类型,因为我需要保持的C创建的代码++ 98'_你使用...模板别名而不是typedefs。这些恰好是在某些编译器中很晚才实现的C++ 11功能。 – sehe 2015-02-23 09:11:35

+0

@ sehe我需要的是显式类型,这可以帮助我重用C++ 98项目中的代码.auto将隐藏与多索引相关的类型,但使用和lambda不会隐藏它们 – user3689849 2015-02-23 23:59:46

回答

2

问题在于,modify会改变元素的顺序,因此迭代可以以相当不可预知的方式重新访问或跳过元素。解决的办法是迭代器做修改之前存储:正是之前

void order_after_modify() 
{ 
    DispatchUsersTable table; 
    table.insert(employee{"jk", "http:cat"}); 
    table.insert(employee{"otaku", "http:joker"}); 
    table.insert(employee{"cba", "http:amota"}); 

    //auto will make codes much easier to read 
    //I type the type explicitly because I need to 
    //maintain the codes created by c++98 
    using Table = DispatchUsersTable::index<name>::type; 
    using Iterator = Table::iterator; 

    Table& name_index= table.get<name>(); 

    std::vector<std::string> names{"onpu", "doremi", "aichan"}; 

    std::vector<Iterator> view; 
    for(Iterator it = table.get<name>().begin();it != table.get<name>().end(); ++it){ 
     view.push_back(it); 
    } 

    for(size_t num = 0;num<view.size();++num){ 
     std::cout<<view[num]->name_<<", "<<view[num]->email_<<std::endl; 
     name_index.modify(view[num], [&](employee &e){ e.name_ = names[num]; }); 
    }    
}