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

亚当

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

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

但是,似乎std::string_view应该可以将其用作密钥。应该有一些方法来比较std::string_viewstd::string改变,因为它们基本上代表了同样的事情。但是无论如何,STL中都没有。

这是一个僵局,我是否被迫编写自己的比较对象std::string_view以及std::string与之配合使用的对象std::unordered_set

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

暗影游侠

我没有一个很好的解决方案,但一个可能的解决方法用最少的自定义代码,以提高内存的使用费用,将取代你std::unordered_set<std::string>与一个std::unordered_map有观点的钥匙,和字符串值(背视图)。

不幸的是,由于进行了小的字符串优化,我们不能依靠std::move保留基础string数据的原始地址,因此类似:

std::string to_insert(...);
mymap.try_emplace(to_insert, std::move(to_insert));

无法正常工作。

相反,它必须是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));

尽管插入有点麻烦,但是简单的成员资格测试将保持简单,因为std::string 定义了一个隐式operator std::string_view,并且std::string_view具有的隐式构造函数char*,所以成员资格测试仍然很简单:

if (mymap.count(some_string)) { ... }

是否some_string是一个char*std::string_viewstd::string

注意:我不会发誓基于两行try_emplace代码的插入代码是合法的,因为我在C ++上有些实践,并且对于unique_ptrmove从中使用相同的表达式中使用a持谨慎态度g++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));

附加说明:只有emplace/ emplace_hint/try_emplace功能,可以安全地用于更新条目mymap中这样的设计。如果在构建地图时两次遇到相同的键,则使用mymap[key] = std::move(to_insert);insert_or_assign中断,因为将保留原始键string_view(引用原始string数据),同时将值替换为new string,从而使string_view的指针无效虽然insert不替换值,但我相信使用它将需要更像具有3衬线的设计try_emplace,因为std::pair如果您尝试同时构造视图和构造的unique_ptr一部分,使插入插入的顺序将是无序的pair

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

从 std::string_view 创建 std::string

std :: string强制转换为const char *在std :: unordered_set <const char *>中找不到

C ++标准:ODR和constexpr std :: string_view

hash <std :: string>与hash <std :: string_view>

如何从 std::string_view 正确创建 std::string?

构造函数采用std :: string_view与std :: string并移动

为什么不支持串联std :: string和std :: string_view?

从大括号的std :: string构造std :: string_view,clang和gcc不赞成-Wconversion

STL容器的std :: string_view

std :: string_view可以复制吗?

noexcept std :: string_view的构造函数

std :: string_view编译时哈希

如何哈希std :: string_view?

printf() std::string_view 的正确方法?

通过引用传递std :: string_view

从std :: unordered_set <char>有效构造std :: string

gsl :: string_span和std :: string_view有何区别?

传递临时std :: string时的string_view行为

如何在C ++中输入std :: string_view?

为什么std :: string_view不具有Assign()和clear()方法?

结合使用std :: string_view和api,期望以null结尾的字符串

带有自己的类和std :: string_view的'operator =='的模棱两可的重载

如何在constexpr string_view上使用std :: string_view :: remove_prefix()

如何将 boost::string_view 转换为 std::string_view?

如何将std :: string_view转换为QStringView

为什么std :: string_view不平凡?

如何通过值或const引用传递std :: string_view

是否保证std :: string_view文字为null终止?

了解 std::string_view 的不同构造