c – 使用string_view进行地图查找
作者:互联网
以下代码无法在最近的编译器上构建(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: no matching member function for call to 'find'
m.find(sv);
~~^~~~
但是不应该找到能够使用类似的类型?
Cppreference提到了以下重载:
模板< K类>迭代器查找(const K& x);
boost :: string_ref也会发生同样的错误.
解决方法:
您需要明确指定transparent comparator(如std::less<>
):
std::map<std::string, int, std::less<>> m;
// ~~~~~~~~~~^
的std ::地图< K,V>将其比较器默认为std::less<K>
(即,不透明的比较器),并且从([associative.reqmts]/p13)开始:
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不是一个可行的候选者.
Heterogeneous comparison lookup for associative containers被添加到c++14.原始提案有可能破坏现有代码.例如:
c.find(x);
在语义上等同于:
key_type key = x;
c.find(key);
特别是,x和key_type之间的转换只发生一次,并且在实际调用之前发生.
异构查找取代了此转换,有利于key和x之间的比较.这可能会导致现有代码中的性能下降(由于每次比较之前的附加转换)或甚至中断编译(如果比较运算符是成员函数,则不会对左侧操作数应用转换):
#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);
}
为了解决这个问题,通过添加linked question中描述的透明比较器的概念,选择了新的行为.
标签:string-view,c,dictionary,c14,c++14 来源: https://codeday.me/bug/20191001/1837495.html