std::unordered_set 中的 std::string_view 和 std::string

Ada*_*dam 10 c++ stl unordered-set string-view c++17

假设您有一个std::unordered_set<std::string>.

您有一个std::string_view要在容器中搜索的对象。问题是,您不想std::string从您的 中创建 a std::string_view,因为这种首先违背了使用的目的std::string_view

不过,好像std::string_view应该可以作为key使用;应该有某种方式来比较std::string_viewand std::string,因为它们基本上代表同一件事。但是没有,无论如何都没有在 STL 中。

这是一个僵局,我是否被迫编写自己的比较对象std::string_viewstd::string与我的对象一起使用std::unordered_set

编辑:这个问题特定于 string_view 对象。“重复”问题不相关。正如预期的那样,我收到了一个独特问题的独特答案。

Sha*_*ger 5

我没有一个很好的解决方案,但一个可能的解决方法是使用最少的自定义代码,以增加内存使用量为代价,将您的替换为具有键视图和值字符串(支持视图)的std::unordered_set<std::string>a 。std::unordered_map

不幸的是,由于小字符串优化,我们不能依赖于std::move保留底层数据的原始地址string,所以类似:

std::string to_insert(...);
mymap.try_emplace(to_insert, std::move(to_insert));
Run Code Online (Sandbox Code Playgroud)

是行不通的。

相反,它必须是 a,std::unordered_map<std::string_view, std::unique_ptr<std::string>>这样我们就可以保留字符串字符的唯一地址,使代码更像:

auto to_insert = std::make_unique<std::string>(...);
mymap.try_emplace(*to_insert, std::move(to_insert));
Run Code Online (Sandbox Code Playgroud)

虽然插入有点难看,但简单的成员资格测试仍然很简单,因为std::string 定义了一个隐式operator std::string_view,并且std::string_view有一个隐式构造函数char*,所以成员资格测试仍然很简单:

if (mymap.count(some_string)) { ... }
Run Code Online (Sandbox Code Playgroud)

是否some_stringchar*,std::string_viewstd::string.

注意:我不会发誓try_emplace基于两行的插入代码是合法的,因为我对 C++ 有点缺乏实践,并且对在我从中获取的unique_ptr同一表达式中使用 a 持谨慎态度;moveg++7.2 上,它似乎有效,并且我认为立即构造的关键参数try_emplace,而构造值的参数被转发使得这很安全,但我承认我对 C++ 求值顺序的理解(或缺乏) )并不完美。如果我做了一些非法的事情,而不仅仅是丑陋的事情,那么修复它需要稍微丑陋的(但肯定是按顺序的):

auto to_insert = std::make_unique<std::string>(...);
std::string_view key{*to_insert};
mymap.try_emplace(std::move(key), std::move(to_insert));
Run Code Online (Sandbox Code Playgroud)

附加说明:只有emplace//函数可以安全地emplace_hint用于更新此设计try_emplace中的条目。如果在构建映射时两次遇到相同的键,则mymap使用mymap[key] = std::move(to_insert);或中断,因为原始的(引用原始的数据)将被保留,而值将被新的替换,从而使的指针无效。虽然不替换值,但我相信使用它需要更像带有 的三行的设​​计,因为如果您尝试构建视图并作为构建的一部分,则插入将是无序的。insert_or_assignstring_viewstringstringstring_viewinserttry_emplacestd::pairunique_ptrpair


归档时间:

查看次数:

3516 次

最近记录:

7 年,2 月 前