为什么在 boost multi_index 容器中插入新元素时所有元素都会被替换?
Why does all elements get replaced when inserting new elements in boost multi_index container?
当我在其他元素正确插入后插入主函数时,但是当我尝试通过函数执行此操作时,所有值都被最后一个元素替换。
请参考以下代码:
struct X
{
std::string panelid; // assume unique
std::string messageid; // assume unique
std::string tid; // assume non-unique
std::string name;
};
struct IndexByPanelID {};
struct IndexByMessageID {};
struct IndexByTID {};
typedef boost::multi_index_container<
X*, // the data type stored
boost::multi_index::indexed_by<
boost::multi_index::hashed_non_unique<
boost::multi_index::tag<IndexByPanelID>,
boost::multi_index::member<X, std::string, &X::panelid>
>,
boost::multi_index::hashed_non_unique<
boost::multi_index::tag<IndexByMessageID>,
boost::multi_index::member<X, std::string, &X::messageid>
>,
boost::multi_index::hashed_non_unique<
boost::multi_index::tag<IndexByTID>,
boost::multi_index::member<X, std::string, &X::tid>
>
>
> Container;
int Insert(X newframe, Container *Cont)
{
auto& indexByL = c.get<IndexByPanelID>();
indexByL.insert(&newframe);
return 0;
}
int main()
{
Container c; // empty container
X x1{ "1", "80", "FE01", "0712"};
X x2{ "2", "80", "FE02", "0713"};
X x3{ "3", "180", "FE03", "0714"};
X x4{ "4", "80", "FE04", "0715"};
Insert(x1,&c); // Doesnt work.
Insert(x2,&c); // Doesnt work.
Insert(x3,&c); // Doesnt work.
Insert(x4,&c); // Doesnt work.
auto& indexByI3 = c.get<IndexByPanelID>();
for(auto i = indexByI3.begin(); i != indexByI3.end(); i++)
{
X *x = *i;
std::cout << x->name << '\n';
std::cout << x->messageid << '\n';
std::cout << x->panelid << '\n';
std::cout << x->tid << '\n';
}
int main()
{
Container c; // empty container
X x1{ "1", "80", "FE01", "0712"};
X x2{ "2", "80", "FE02", "0713"};
X x3{ "3", "180", "FE03", "0714"};
X x4{ "4", "80", "FE04", "0715"};
// Insert some elements
auto& indexByL = c.get<IndexByPanelID>();
indexByL.insert(&x1); //works fine.
indexByL.insert(&x2); //works fine.
indexByL.insert(&x3); //works fine.
indexByL.insert(&x4); //works fine.
auto& indexByI3 = c.get<IndexByPanelID>();
for(auto i = indexByI3.begin(); i != indexByI3.end(); i++)
{
X *x = *i;
std::cout << x->name << '\n';
std::cout << x->messageid << '\n';
std::cout << x->panelid << '\n';
std::cout << x->tid << '\n';
}
}
输出第一个主要:
0715
80
4
FE04
0715
80
4
FE04
0715
80
4
FE04
0715
80
4
FE04
第二主线:
0712
80
1
FE01
0713
80
2
FE02
0714
180
3
FE03
0715
80
4
FE04
您没有提供工作代码。你过度使用指针。第一个错误使代码可以编译:
int Insert(X newframe, Container *Cont)
应该是
int Insert(X newframe, Container& c)
真正的问题是您存储的是指针,而不是框架。在 Insert
函数中插入的指针是悬空的(它们指向参数 frame
,它在 Insert
的 return 之后消失了),所以行为是 Undefined.
最后,当插入新项目时,不需要通过额外的环跳到 select 一个特定的索引(除非你需要一个特定于索引的迭代器到新插入的元素.不过,你好像根本就没有return值)。
这是一个带有修复的简化版本:
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/hashed_index.hpp>
#include <boost/multi_index/member.hpp>
#include <iostream>
#include <iomanip>
namespace bmi = boost::multi_index;
#include <string>
struct X { std::string panelid, messageid, tid, name; };
using Container = bmi::multi_index_container<
X,
bmi::indexed_by< //
bmi::hashed_non_unique< //
bmi::tag<struct ByPanelID>, //
bmi::member<X, std::string, &X::panelid> //
>, //
bmi::hashed_non_unique< //
bmi::tag<struct ByMessageID>, //
bmi::member<X, std::string, &X::messageid> //
>, //
bmi::hashed_non_unique< //
bmi::tag<struct ByTID>, //
bmi::member<X, std::string, &X::tid> //
>>>;
void Insert(X newframe, Container &c) {
c.insert(std::move(newframe));
}
int main()
{
Container c; // empty container
Insert({ "1", "80", "FE01", "0712"},c);
Insert({ "2", "80", "FE02", "0713"},c);
Insert({ "3", "180", "FE03", "0714"},c);
Insert({ "4", "80", "FE04", "0715"},c);
for (auto& [panelid, messageid, tid, name] : c.get<ByPanelID>()) {
std::cout << std::quoted(name) << ' ' //
<< std::quoted(messageid) << ' ' //
<< std::quoted(panelid) << ' ' //
<< std::quoted(tid) << '\n';
}
}
版画
"0712" "80" "1" "FE01"
"0713" "80" "2" "FE02"
"0714" "180" "3" "FE03"
"0715" "80" "4" "FE04"
事实上,对于这个简单的演示,您可以做得更简单:https://godbolt.org/z/hbeeGd7ox
当我在其他元素正确插入后插入主函数时,但是当我尝试通过函数执行此操作时,所有值都被最后一个元素替换。
请参考以下代码:
struct X
{
std::string panelid; // assume unique
std::string messageid; // assume unique
std::string tid; // assume non-unique
std::string name;
};
struct IndexByPanelID {};
struct IndexByMessageID {};
struct IndexByTID {};
typedef boost::multi_index_container<
X*, // the data type stored
boost::multi_index::indexed_by<
boost::multi_index::hashed_non_unique<
boost::multi_index::tag<IndexByPanelID>,
boost::multi_index::member<X, std::string, &X::panelid>
>,
boost::multi_index::hashed_non_unique<
boost::multi_index::tag<IndexByMessageID>,
boost::multi_index::member<X, std::string, &X::messageid>
>,
boost::multi_index::hashed_non_unique<
boost::multi_index::tag<IndexByTID>,
boost::multi_index::member<X, std::string, &X::tid>
>
>
> Container;
int Insert(X newframe, Container *Cont)
{
auto& indexByL = c.get<IndexByPanelID>();
indexByL.insert(&newframe);
return 0;
}
int main()
{
Container c; // empty container
X x1{ "1", "80", "FE01", "0712"};
X x2{ "2", "80", "FE02", "0713"};
X x3{ "3", "180", "FE03", "0714"};
X x4{ "4", "80", "FE04", "0715"};
Insert(x1,&c); // Doesnt work.
Insert(x2,&c); // Doesnt work.
Insert(x3,&c); // Doesnt work.
Insert(x4,&c); // Doesnt work.
auto& indexByI3 = c.get<IndexByPanelID>();
for(auto i = indexByI3.begin(); i != indexByI3.end(); i++)
{
X *x = *i;
std::cout << x->name << '\n';
std::cout << x->messageid << '\n';
std::cout << x->panelid << '\n';
std::cout << x->tid << '\n';
}
int main()
{
Container c; // empty container
X x1{ "1", "80", "FE01", "0712"};
X x2{ "2", "80", "FE02", "0713"};
X x3{ "3", "180", "FE03", "0714"};
X x4{ "4", "80", "FE04", "0715"};
// Insert some elements
auto& indexByL = c.get<IndexByPanelID>();
indexByL.insert(&x1); //works fine.
indexByL.insert(&x2); //works fine.
indexByL.insert(&x3); //works fine.
indexByL.insert(&x4); //works fine.
auto& indexByI3 = c.get<IndexByPanelID>();
for(auto i = indexByI3.begin(); i != indexByI3.end(); i++)
{
X *x = *i;
std::cout << x->name << '\n';
std::cout << x->messageid << '\n';
std::cout << x->panelid << '\n';
std::cout << x->tid << '\n';
}
}
输出第一个主要:
0715
80
4
FE04
0715
80
4
FE04
0715
80
4
FE04
0715
80
4
FE04
第二主线:
0712
80
1
FE01
0713
80
2
FE02
0714
180
3
FE03
0715
80
4
FE04
您没有提供工作代码。你过度使用指针。第一个错误使代码可以编译:
int Insert(X newframe, Container *Cont)
应该是
int Insert(X newframe, Container& c)
真正的问题是您存储的是指针,而不是框架。在 Insert
函数中插入的指针是悬空的(它们指向参数 frame
,它在 Insert
的 return 之后消失了),所以行为是 Undefined.
最后,当插入新项目时,不需要通过额外的环跳到 select 一个特定的索引(除非你需要一个特定于索引的迭代器到新插入的元素.不过,你好像根本就没有return值)。
这是一个带有修复的简化版本:
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/hashed_index.hpp>
#include <boost/multi_index/member.hpp>
#include <iostream>
#include <iomanip>
namespace bmi = boost::multi_index;
#include <string>
struct X { std::string panelid, messageid, tid, name; };
using Container = bmi::multi_index_container<
X,
bmi::indexed_by< //
bmi::hashed_non_unique< //
bmi::tag<struct ByPanelID>, //
bmi::member<X, std::string, &X::panelid> //
>, //
bmi::hashed_non_unique< //
bmi::tag<struct ByMessageID>, //
bmi::member<X, std::string, &X::messageid> //
>, //
bmi::hashed_non_unique< //
bmi::tag<struct ByTID>, //
bmi::member<X, std::string, &X::tid> //
>>>;
void Insert(X newframe, Container &c) {
c.insert(std::move(newframe));
}
int main()
{
Container c; // empty container
Insert({ "1", "80", "FE01", "0712"},c);
Insert({ "2", "80", "FE02", "0713"},c);
Insert({ "3", "180", "FE03", "0714"},c);
Insert({ "4", "80", "FE04", "0715"},c);
for (auto& [panelid, messageid, tid, name] : c.get<ByPanelID>()) {
std::cout << std::quoted(name) << ' ' //
<< std::quoted(messageid) << ' ' //
<< std::quoted(panelid) << ' ' //
<< std::quoted(tid) << '\n';
}
}
版画
"0712" "80" "1" "FE01"
"0713" "80" "2" "FE02"
"0714" "180" "3" "FE03"
"0715" "80" "4" "FE04"
事实上,对于这个简单的演示,您可以做得更简单:https://godbolt.org/z/hbeeGd7ox