使用 std::map 存储在 std::any 中,然后通过 std::any_cast 访问



我正在尝试理解以下代码的结果:

template<typename KeyTypeT, typename ValueTypeT>
class MapWrapper {
std::any _container;
MapWrapper() {
_container = std::map<KeyTypeT, ValueTypeT>();
}
void insert(KeyTypeT key, ValueTypeT value) {
auto originalMap = std::any_cast<std::map<KeyTypeT, ValueTypeT>>(_container);
std::cout << "count is " << originalMap.size() << std::endl;
auto afterInsertion = std::any_cast<std::map<KeyTypeT, ValueTypeT>>(_container);
afterInsertion.insert(std::make_pair(key, value));
std::cout << "count is " << afterInsertion.size() << std::endl;
auto originalMapAfterInsertion = std::any_cast<std::map<KeyTypeT, ValueTypeT>>(_container);
std::cout << "count is " << originalMapAfterInsertion.size() << std::endl;

_container = afterInsertion;
auto originalMapAfterAssignement = std::any_cast<std::map<KeyTypeT, ValueTypeT>>(_container);
std::cout << "count is " << originalMapAfterAssignement.size() << std::endl;
}
};

结果如下:

Test Results:
count is 0
count is 1
count is 0 // why is this not 1?
count is 1

我的问题是为什么_container直到我完成作业后才包含新插入的密钥?

std::any_cast是否将副本返回给std::map<KeyTypeT, ValueTypeT>?我本来希望它返回原始地图。有没有办法修改存储在std::any中的原始地图?

你正在使用的any_cast的重载给你一个any持有的值的副本,而不是对它的引用。因此,您插入的mapany持有的map不同。

如果要直接修改any持有的内容,则需要使用通过指针获取any的重载之一(即#5(:

std::any a = 1;
int* p = std::any_cast<int>(&a); // <== like this
assert(p);
*p = 42;
assert(std::any_cast<int>(a) == 42);

或者,您可以在any_cast中显式提供引用类型:

std::any a = 1;
std::any_cast<int&>(a) = 42; // <== int&, not int
assert(std::any_cast<int>(a) == 42);

另请注意,即使any_cast本身没有给你一份副本,你也是通过写来自己制作一份:

auto originalMap = ...;

而不是引用结果。所以你可能想要:

auto& map = std::any_cast<std::map<...>&>(_container);

您的any_cast正在返回副本 - 尝试返回指向所包含对象的指针或换行 std::reference_wrapper

最新更新