使用string_view进行地图查找 [英] Use of string_view for map lookup

查看:154
本文介绍了使用string_view进行地图查找的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下代码无法在最新的编译器(g ++-5.3,clang ++-3.7)上构建.

The following code fails to build on recent compilers (g++-5.3, clang++-3.7).

#include <map>
#include <functional>
#include <experimental/string_view>

void f()
{
    using namespace std;
    using namespace std::experimental;
    map<string, int> m;
    string s = "foo";
    string_view sv(s);
    m.find(sv);
}

clang返回的错误:

Error returned by clang :

error: no matching member function for call to 'find'
    m.find(sv);
    ~~^~~~

但是find不能使用可比较的类型吗? Cppreference提到了以下重载:

But shouldn't find be able to use comparable types ? Cppreference mentions the following overload :

template< class K > iterator find( const K& x );

boost::string_ref也会发生相同的错误.

The same error happens with boost::string_ref.

推荐答案

您需要指定 透明比较器 明确显示(例如 std::less<> ):

You need to specify a transparent comparator explicitly (like std::less<>):

std::map<std::string, int, std::less<>> m;
//                         ~~~~~~~~~~^

std::map<K,V>默认将其比较器设置为 std::less<K> (即, em> non-transparent 一个),以及由于( [associative.reqmts] /p13 ):

std::map<K,V> defaults its comparator to std::less<K> (i.e., a non-transparent one), and since ([associative.reqmts]/p13):

除非 qualified-id Compare::is_transparent有效,否则成员函数模板findcountlower_boundupper_boundequal_range不应参与重载解析.并表示类型(14.8.2).

The member function templates find, count, lower_bound, upper_bound, and equal_range shall not participate in overload resolution unless the qualified-id Compare::is_transparent is valid and denotes a type (14.8.2).

模板成员函数find不是可行的候选对象.

the template member function find is not a viable candidate.

关联容器的异构比较查找已添加到.原始建议可能会破坏现有代码.例如:

Heterogeneous comparison lookup for associative containers was added to c++14. The original proposal risked breaking existing code. For example:

c.find(x);

在语义上等同于:

key_type key = x;
c.find(key);

尤其是,xkey_type之间的转换仅发生一次 ,并且发生在实际调用之前 .

In particular, the conversion between x and key_type happens only once, and before the actual call.

异构查找替换了此转换,以便在keyx之间进行比较.这可能会导致现有代码的性能下降(由于每次比较之前都要进行附加转换),甚至中断编译(如果比较运算符是成员函数,则不会对左侧操作数应用转换):

Heterogenous lookup replaces this conversion in favour of a comparison between key and x. This may lead to a drop in performance in existing code (due to addtional conversion before each comparison) or even break compilation (if the comparison operator is a member function, it will not apply conversion for a left-hand side operand):

#include <set>
#include <functional>

struct A
{
    int i;

    A(int i) : i(i) {}
};

bool operator<(const A& lhs, const A& rhs)
{
    return lhs.i < rhs.i;
}

int main()
{
    std::set<A, std::less<>> s{{1}, {2}, {3}, {4}};
    s.find(5);
}

演示

为解决此问题,通过添加链接的问题.

To resolve this the new behaviour was made opt-in by adding the concept of transparent comparators as described in the linked question.

这篇关于使用string_view进行地图查找的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆