指向模板参数类型

时间:2016-08-11 12:46:09

标签: c++ templates pointers containers

我正在尝试创建自己的容器,这只是std::unordered_map的包装器,它使用std::vector跟踪插入顺序。

这是我的(简化)课程:

template <class tKey, class tValue>
class OrderedMap
{
public:
    typedef size_t tSize;
    inline bool contains(const tKey& key) const { return map_.count(key) > 0; }
    inline tValue& at(const tSize& index) { return vector_[index]; }
    inline tValue& operator [](const tKey& key)
    {
        if(!contains(key)) { throw std::out_of_range("Unknown key"); }
        return *map_[key];
    }
    inline void push_back(const tKey& key, const tValue& value)
    {
        vector_.push_back(value);
        map_[key] = &vector_[size()-1];
    }
    inline void set(const tKey& key, const tValue& value)
    {
        if(!contains(key)) push_back(key, value);
        else *map_[key] = value;
    }

private:
    std::vector<tValue> vector_;
    std::unordered_map<tKey, tValue*> map_;
};

当我尝试执行此代码示例时:

OrderedMap<std::string, std::vector<std::string> > myContainer;
myContainer.set("1", {"11", "12"});
myContainer.set("2", {"21", "22"});
auto myValues = myContainer["1"];

当我尝试访问数据时发生了错误。在此示例中,当程序尝试将数据复制到myValues时,它会触发一个异常,告诉我向量太长,但在我的代码中的某个地方,它以读取结束取消引用operator []中的指向者时出现访问冲突错误。

显然我在某个地方犯了一个错误,但我找不到,所以我的代码出了什么问题? 我错过了关于模板参数和引用它们的一些内容吗?

编辑:我正在使用MSVC 12.0编译Windows。

1 个答案:

答案 0 :(得分:3)

将指针/引用/迭代器存储到不断增长的向量中的元素通常是一个非常糟糕的主意。在

inline void push_back(const tKey& key, const tValue& value)
{
    vector_.push_back(value);
    map_[key] = &vector_[size()-1];
}

将元素添加到矢量中,然后在地图中存储指向该元素的指针。这样做的问题是如果你继续向向量添加项目,向量将需要增长,这意味着分配新的内存。这意味着向量中的元素不再是以前的位置,这意味着地图中的所有指针现在都悬空(指向垃圾)。

简单的解决方法是将元素存储在两个地方。您还可以创建std::shared_ptr并将shared_ptr存储在两个容器中。

相关问题