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

mar*_*f78 3 c++ c++17

我试图理解以下代码的结果:

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;
    }
};
Run Code Online (Sandbox Code Playgroud)

结果如下:

Test Results:
count is 0
count is 1
count is 0 // why is this not 1?
count is 1
Run Code Online (Sandbox Code Playgroud)

我的问题是为什么_container在我完成任务之前不包含新插入的密钥?

正在std::any_cast将副本返回给std::map<KeyTypeT, ValueTypeT>?我原以为它会返回原始地图.有没有办法修改存储在原始地图中std::any

Bar*_*rry 7

any_cast您正在使用的超载(#2)为您提供了该值所持有的值的副本any,而不是对它的引用.所以map你插入mapany是与持有的不同.

如果你想直接修改它所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);
Run Code Online (Sandbox Code Playgroud)

或者您可以明确地将引用类型提供到any_cast:

std::any a = 1;
std::any_cast<int&>(a) = 42; // <== int&, not int
assert(std::any_cast<int>(a) == 42);
Run Code Online (Sandbox Code Playgroud)

另请注意,即使any_cast本身没有给你一份副本,你也可以自己写一篇:

auto originalMap = ...;
Run Code Online (Sandbox Code Playgroud)

而不是参考结果.所以你可能想要:

auto& map = std::any_cast<std::map<...>&>(_container);
Run Code Online (Sandbox Code Playgroud)