使用string_view进行地图查找 [英] Use of string_view for map lookup
问题描述
以下代码无法在最新的编译器(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
有效,否则成员函数模板find
,count
,lower_bound
,upper_bound
和equal_range
不应参与重载解析.并表示类型(14.8.2).
The member function templates
find
,count
,lower_bound
,upper_bound
, andequal_range
shall not participate in overload resolution unless the qualified-idCompare::is_transparent
is valid and denotes a type (14.8.2).
模板成员函数find
不是可行的候选对象.
the template member function find
is not a viable candidate.
关联容器的异构比较查找已添加到c ++ 14 .原始建议可能会破坏现有代码.例如:
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);
尤其是,x
和key_type
之间的转换仅发生一次 ,并且发生在实际调用之前 .
In particular, the conversion between x
and key_type
happens only once, and before the actual call.
异构查找替换了此转换,以便在key
和x
之间进行比较.这可能会导致现有代码的性能下降(由于每次比较之前都要进行附加转换),甚至中断编译(如果比较运算符是成员函数,则不会对左侧操作数应用转换):>
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屋!