在std :: map中引用为键

时间:2010-07-13 09:43:59

标签: c++ map reference

假设一些数据结构:

typedef struct {
    std::string s;
    int i;
} data;

如果我在data.s类型的地图中添加data的实例时使用字段std::map<std::string&, data>作为键,那么字符串是否会被复制?擦除地图元素是否安全,因为引用将变为无效?

这些问题的答案也适用于unordered_map

修改

这是我目前的解决方案......但是向地图添加迭代器是UGLY:

typedef struct {
    const std::string* s;
    int i;
} data;

std::map<std::string, data> map;
typedef std::map<std::string, data>::iterator iterator;

// add an element to the map
iterator add_element(const std::string& s) {
    std::pair<iterator, bool> p = states.insert(std::make_pair(s, data()));
    iterator i = p.first;
    if(p.second) {
        data& d = (*i).second;
        d.s = &(*i).first;
    }
    return i;
}

4 个答案:

答案 0 :(得分:17)

您可能需要查看boost.ref。它提供了一个包装器,允许在STL容器中使用引用,如下所示:

std::map<boost::reference_wrapper<std::string>, data>

从C ++ 11开始,这是标准的一部分(在此之前,实现TR1的编译器也在std::tr1命名空间中提供它。)

答案 1 :(得分:11)

您无法在标准库容器中存储引用 - 您的地图应如下所示:

map <string,data> mymap;

地图将为您管理密钥字符串和结构实例,它们将是副本。在这方面,mapunordered_map都以相同的方式工作,与所有其他标准库容器一样。

请注意,在C ++中,您不需要typedef来声明结构:

struct data {
    std::string s;
    int i;
};

答案 2 :(得分:0)

您无法使用该参考。地图可以复制内容。这是我猜的实现依赖。

但是使用微软STL进行了测试。

struct data
{
            data(data const& rhs)
            {
               a new object will be created here
            }
            std::string s;
            int i; 
};

向地图添加一些对象,您将遇到复制构造函数。 这应该使您的参考无效。

答案 3 :(得分:0)

如果您选择指针而不是对象,我认为不会有很大的性能提升。只有在管理需要容纳在容器内的大量现有字符串对象的数据时才执行此操作。在破坏容器之前,还必须手动管理对象的破坏。