在std :: map中引用为键

Gio*_*hal 13 c++ reference map

假设一些数据结构:

typedef struct {
    std::string s;
    int i;
} data;
Run Code Online (Sandbox Code Playgroud)

如果我在类型映射中data.s添加实例时使用该字段作为键,那么字符串是否会被复制?擦除地图元素是否安全,因为引用将变为无效?datastd::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;
}
Run Code Online (Sandbox Code Playgroud)

Bjö*_*lex 17

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

std::map<boost::reference_wrapper<std::string>, data>
Run Code Online (Sandbox Code Playgroud)

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


小智 11

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

map <string,data> mymap;
Run Code Online (Sandbox Code Playgroud)

地图将为您管理密钥字符串和结构实例,它们将是副本.无论mapunordered_map工作在这方面同样的方式,因为这样做的所有其他标准库容器.

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

struct data {
    std::string s;
    int i;
};
Run Code Online (Sandbox Code Playgroud)

  • @Helltone References很难正确地用作结构或类的成员 - 这实际上并不是它们的用途.相反,您应该使用指针,或者完全省略struct中的字符串. (2认同)