gpt4 book ai didi

c++ - 为什么不能将 `boost::multi_index replace` 用于指针类型?

转载 作者:搜寻专家 更新时间:2023-10-31 00:35:58 27 4
gpt4 key购买 nike

简答:用户修改,接受的答案中的详细信息以及 this answer

我正在尝试使用一个包含指针类型的 boost::multi_index_container。在我看来,replace 功能已损坏,我想知道我做错了什么。

以下代码演示了两种情况:第一种是容器保存数据的拷贝(正常工作),第二种是容器保存指向数据的指针(失败)。

using namespace boost::multi_index;
using boost::multi_index_container;

struct Data
{
int key1;
int key2;
};

using DataContainer =
multi_index_container<
Data,
indexed_by<
hashed_unique<member<Data, int, &Data::key1>>,
hashed_unique<member<Data, int, &Data::key2>>>>;

using DataPtrContainer =
multi_index_container<
Data*,
indexed_by<
hashed_unique<member<Data, int, &Data::key1>>,
hashed_unique<member<Data, int, &Data::key2>>>>;

TEST(DummyTest, Test1)
{
Data data{1,2};
DataContainer dataContainer;
dataContainer.insert(data);

EXPECT_EQ(1, dataContainer.get<0>().find(1)->key1);
EXPECT_EQ(2, dataContainer.get<0>().find(1)->key2);

auto iter = dataContainer.get<0>().find(1);
Data d = *iter;
d.key2 = 5;
dataContainer.replace(iter, d);

EXPECT_EQ(1, dataContainer.get<1>().find(5)->key1);
EXPECT_EQ(5, dataContainer.get<1>().find(5)->key2);

}

TEST(DummyTest, Test2)
{
Data* data = new Data{1,2};
DataPtrContainer dataContainer;
dataContainer.insert(data);

EXPECT_EQ(1, (*dataContainer.get<0>().find(1))->key1);
EXPECT_EQ(2, (*dataContainer.get<0>().find(1))->key2);

auto iter = dataContainer.get<0>().find(1);
Data* d = *iter;
d->key2 = 5;
dataContainer.replace(iter, d);

EXPECT_EQ(1, (*dataContainer.get<1>().find(5))->key1); // fail as the iterator not dereferencable
EXPECT_EQ(5, (*dataContainer.get<1>().find(5))->key2); // fail as the iterator not dereferencable

}

最佳答案

好的,这不是 Boost.MultiIndex 中的错误,而是您代码中的一个微妙的契约违规。无指针版本:

auto iter = dataContainer.get<0>().find(1);
Data d = *iter;
d.key2 = 5;
dataContainer.replace(iter, d);

将包含值的拷贝复制到 d 中,对其进行修改,然后使用它进行替换:到目前为止一切顺利。但是指针版本正在打破不变量:

auto iter = dataContainer.get<0>().find(1);
Data* d = *iter;
d->key2 = 5; // #1: invariant breach here
dataContainer.replace(iter, d); // #2: unexpected behavior ensues

在 #1 中,您在未经 dataContainer 同意或不知情的情况下修改了它的内部键:一旦您这样做了,被触及的元素就会被错误地索引。这类似于在无指针版本中抛弃 constness:

auto iter = dataContainer.get<0>().find(1);
const Data& d = *iter;
const_cast<Data&>(d).key2 = 5;

因此,当执行#2 时,datacontainer 不会怀疑您更改了它的 key ,只是验证您建议的替换 d 是否等同于它已经有,但什么都不做(然后没有重新索引)。

关于c++ - 为什么不能将 `boost::multi_index replace` 用于指针类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22777768/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com