在无序映射中使用 string_view 作为键的安全方法

Joh*_*ohn 5 c++ c++17

我的类型 Val 包含 std::string thekey。

struct Val
{
std::string thekey;
float somedata;
}
Run Code Online (Sandbox Code Playgroud)

我想将我的类型放入无序映射中,以 key 作为键。出于内存和避免转换的原因,我希望将 std::string_view 作为键类型。使用 unique_ptr 时是否可以创建指向 val.thekey 的密钥?

std::unique_ptr<Val> valptr = ...;
std::unordered_map<std::string_view,std::unique_ptr<Val>> themap;
themap[std::string_view(valptr->thekey)] = std::move(valptr); // is this ok and safe?
Run Code Online (Sandbox Code Playgroud)

Use*_*ess 5

在无序映射中使用 string_view 作为键的安全方法

一般来说,没有一个,因为视图底层的存储可能随时发生变化,从而使您的地图不变量无效。

关联容器通常拥有一个const密钥,正是为了避免这种情况。

在您的具体情况下,使用合适的散列和相等函子更有意义std::unordered_set<Val, ValKeyHash, ValKeyEqual>


编辑,这些合适的函子只是

struct ValKeyHash {
    std::size_t operator() (Val const &v)
    {
        return std::hash<std::string>{}(v.thekey);
    }
};

struct ValKeyEqual {
    bool operator() (Val const& a, Val const& b)
    {
        return a.thekey == b.thekey;
    }
};
Run Code Online (Sandbox Code Playgroud)

显然,这给我们带来了使用临时Val{key, dummy_data}查找的稍微不愉快的要求,至少在我们可以在另一个答案中使用 C++20 透明/投影版本之前。