为什么我的向量不返回最后存储的值?

Why is my vector not returning the last stored value?

我正在尝试在 unordered_map 中使用相同的键存储两个不同的值。为此,我使用了一个向量来保存这些值。 如果在调用 store->get() 时指定了索引,我想调用以前存储的值,否则它 returns 只是最新值。 当我 运行 我的测试代码时,它总是 returns 向量中存储的第一个值。当我调试时,我确实看到第二个值存储在 set() 的向量中。但是当调用 get() 时,向量只包含第一个元素。怎么可能?

using namespace std;
int main() {
    class store
    {
        std::unordered_map<string, std::vector<string>> container;

    public:
        int set(string key, string value)
        {
            //find if the key exist
            if (container.find(key) != container.end())
            {
                //if yes insert at last position and return last index
                auto vec = container[key];
                vec.push_back(value);

                return vec.size() - 1;
            }
            //if not insert in vector and return index 0
            else
            {
                std::vector<string> tmpVec;
                tmpVec.push_back(value);
                container[key] = tmpVec;
                return 0;
            }
        };
        string get(string key, int timestamp = -1)
        {
            if (container.find(key) != container.end())
            {
                auto vec = container[key];

                if (timestamp >= 0)
                {
                    return vec[timestamp];
                }
                else
                {
                    return vec[vec.size() - 1];
                }
            }
            return "";
        };
    };

    store* store1 = new store();

    auto timestamp1 = store1->set("foo", "bar");
    store1->set("foo", "hello");

    cout << "value at timestamp1: " << store1->get("foo", timestamp1) << endl;;
    cout << "last value:" << store1->get("foo") << endl; //expected hello

    return 0;
}

你的问题出在这两行:

auto vec = container[key];
vec.push_back(value);

当您对 vec 进行赋值时,您创建了相关向量的一个新副本。把上面两行改成

container[key].push_back(value);

你应该会得到预期的结果。此外,不要使用 using namespace std;!要么完全符合条件(例如 std::cout),要么只使用您需要的(using std::cout;)。您可能还想为您的用例考虑 std::unordered_multimap

问题出在您执行此操作的 set 函数中:

auto vec = container[key];

这里你创建了一个copy的vector,并且只将值添加到副本中。原始向量保持不变。

您可以使用 references 来获取对原始向量的引用:

auto& vec = container[key];
//  ^
// Note ampersand here, meaning vec is a reference

事实上,如果您还记得[]std::unordered_map 重载运算符将 创建 一个元素,那么set 函数可以大大简化如果它不存在,这意味着您不需要先 find 元素:

int set(string key, string value)
{
    // Use existing element from map if it exists,
    // or create a new if it doesn't
    container[key].push_back(value);

    // The vector is guaranteed to exist at this point,
    // and contain at least one element
    return container[key].size() - 1;
}