multi_index composite_key 替换为迭代器
是否有办法循环访问 boost::multi_index 中的索引并执行替换?
#include <iostream>
#include <string>
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/composite_key.hpp>
#include <boost/multi_index/member.hpp>
#include <boost/multi_index/ordered_index.hpp>
using namespace boost::multi_index;
using namespace std;
struct name_record
{
public:
name_record(string given_name_,string family_name_,string other_name_)
{
given_name=given_name_;
family_name=family_name_;
other_name=other_name_;
}
string given_name;
string family_name;
string other_name;
string get_name() const { return given_name + " " + family_name + " " + other_name; }
void setnew(string chg)
{
given_name = given_name + chg;
family_name = family_name + chg;
}
};
struct NameIndex{};
typedef multi_index_container<
name_record,
indexed_by<
ordered_non_unique<
tag<NameIndex>,
composite_key
<
name_record,
BOOST_MULTI_INDEX_MEMBER(name_record,string, name_record::given_name),
BOOST_MULTI_INDEX_MEMBER(name_record,string, name_record::family_name)
>
>
>
> name_record_set;
typedef boost::multi_index::index<name_record_set,NameIndex>::type::iterator IteratorType;
typedef boost::multi_index::index<name_record_set,NameIndex>::type NameIndexType;
void printContainer(name_record_set & ns)
{
cout << endl << "PrintContainer" << endl << "-------------" << endl;
IteratorType it1 = ns.begin();
IteratorType it2 = ns.end ();
while (it1 != it2)
{
cout<<it1->get_name()<<endl;
it1++;
}
cout << "--------------" << endl << endl;
}
void modifyContainer(name_record_set & ns)
{
cout << endl << "ModifyContainer" << endl << "-------------" << endl;
IteratorType it3;
IteratorType it4;
NameIndexType & idx1 = ns.get<NameIndex>();
IteratorType it1 = idx1.begin();
IteratorType it2 = idx1.end();
while (it1 != it2)
{
cout<<it1->get_name()<<endl;
name_record nr = *it1;
nr.setnew("_CHG");
bool res = idx1.replace(it1,nr);
cout << "result is: " << res << endl;
it1++;
}
cout << "--------------" << endl << endl;
}
int main()
{
name_record_set ns;
ns.insert( name_record("Joe","Smith","ENTRY1") );
ns.insert( name_record("Robert","Brown","ENTRY2") );
ns.insert( name_record("Robert","Nightingale","ENTRY3") );
ns.insert( name_record("Marc","Tuxedo","ENTRY4") );
printContainer (ns);
modifyContainer (ns);
printContainer (ns);
return 0;
}
PrintContainer
-------------
Joe Smith ENTRY1
Marc Tuxedo ENTRY4
Robert Brown ENTRY2
Robert Nightingale ENTRY3
--------------
ModifyContainer
-------------
Joe Smith ENTRY1
result is: 1
Marc Tuxedo ENTRY4
result is: 1
Robert Brown ENTRY2
result is: 1
--------------
PrintContainer
-------------
Joe_CHG Smith_CHG ENTRY1
Marc_CHG Tuxedo_CHG ENTRY4
Robert Nightingale ENTRY3
Robert_CHG Brown_CHG ENTRY2
--------------
Is there anyway to loop through an index in a boost::multi_index and perform a replace?
#include <iostream>
#include <string>
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/composite_key.hpp>
#include <boost/multi_index/member.hpp>
#include <boost/multi_index/ordered_index.hpp>
using namespace boost::multi_index;
using namespace std;
struct name_record
{
public:
name_record(string given_name_,string family_name_,string other_name_)
{
given_name=given_name_;
family_name=family_name_;
other_name=other_name_;
}
string given_name;
string family_name;
string other_name;
string get_name() const { return given_name + " " + family_name + " " + other_name; }
void setnew(string chg)
{
given_name = given_name + chg;
family_name = family_name + chg;
}
};
struct NameIndex{};
typedef multi_index_container<
name_record,
indexed_by<
ordered_non_unique<
tag<NameIndex>,
composite_key
<
name_record,
BOOST_MULTI_INDEX_MEMBER(name_record,string, name_record::given_name),
BOOST_MULTI_INDEX_MEMBER(name_record,string, name_record::family_name)
>
>
>
> name_record_set;
typedef boost::multi_index::index<name_record_set,NameIndex>::type::iterator IteratorType;
typedef boost::multi_index::index<name_record_set,NameIndex>::type NameIndexType;
void printContainer(name_record_set & ns)
{
cout << endl << "PrintContainer" << endl << "-------------" << endl;
IteratorType it1 = ns.begin();
IteratorType it2 = ns.end ();
while (it1 != it2)
{
cout<<it1->get_name()<<endl;
it1++;
}
cout << "--------------" << endl << endl;
}
void modifyContainer(name_record_set & ns)
{
cout << endl << "ModifyContainer" << endl << "-------------" << endl;
IteratorType it3;
IteratorType it4;
NameIndexType & idx1 = ns.get<NameIndex>();
IteratorType it1 = idx1.begin();
IteratorType it2 = idx1.end();
while (it1 != it2)
{
cout<<it1->get_name()<<endl;
name_record nr = *it1;
nr.setnew("_CHG");
bool res = idx1.replace(it1,nr);
cout << "result is: " << res << endl;
it1++;
}
cout << "--------------" << endl << endl;
}
int main()
{
name_record_set ns;
ns.insert( name_record("Joe","Smith","ENTRY1") );
ns.insert( name_record("Robert","Brown","ENTRY2") );
ns.insert( name_record("Robert","Nightingale","ENTRY3") );
ns.insert( name_record("Marc","Tuxedo","ENTRY4") );
printContainer (ns);
modifyContainer (ns);
printContainer (ns);
return 0;
}
PrintContainer
-------------
Joe Smith ENTRY1
Marc Tuxedo ENTRY4
Robert Brown ENTRY2
Robert Nightingale ENTRY3
--------------
ModifyContainer
-------------
Joe Smith ENTRY1
result is: 1
Marc Tuxedo ENTRY4
result is: 1
Robert Brown ENTRY2
result is: 1
--------------
PrintContainer
-------------
Joe_CHG Smith_CHG ENTRY1
Marc_CHG Tuxedo_CHG ENTRY4
Robert Nightingale ENTRY3
Robert_CHG Brown_CHG ENTRY2
--------------
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这段代码的问题在于,一旦替换了元素
x
,它就会自动重新排序到新位置,因此it1
会一直指向x
,“跳跃”序列并可能跳过或重新访问元素。解决方案是在开始替换之前添加一个间接级别并收集所有元素的迭代器:
如果您之前没有使用过它,则
make_counting_iterator
位只是填充向量的一种紧凑方式带有对 ns 的所有元素的迭代器。The problem with this code is that, once you've replaced an element
x
, this is automatically reordered to its new position, so thatit1
, which keeps pointing tox
, "jumps" through the sequence and might skip or revisit elements.The solution is to add a level of indirection and collect iterators to all the elements before beginning the replacements:
In case you didn't use it before, the
make_counting_iterator
bit is just a compact way to populate the vector with iterators to all the elements ofns
.