#include <map>
#include <string>
#include <string_view>
using namespace std;
int main()
{
string_view key = "hello";
map<string, int, less<>> coll;
coll.find(key); // ok
coll[key] = 0; // !!! error ???
}
密钥类型为std::string
,兼容类型为std::string_view
。从C ++ 14开始,std::map::find
允许使用兼容密钥;所以coll.find(key);
没问题。
然而,为什么不 coll[key] = 0;
也可以?
答案 0 :(得分:4)
coll.find(key)
只需key
与实际密钥类型进行可比较,std::string_view
与std::string
相当。但是,为了能够将key
插入coll
,key
需要可兑换到std::string
,而不是{{1}} ,无论如何)。
答案 1 :(得分:3)
N3465中描述了背后的基本原理。
从概念上讲,扩展包括基于严格的弱排序替换原始公式,其中一个依赖于序列划分的概念,正如David Abrahams首先提出的那样。不幸的是,这个扩展过程还没有针对关联容器的查找操作进行,关联容器仍然是根据严格的弱顺序制定的,因此不允许异构 比较。
从N3465获取此示例,并稍微修改一下:
struct name_entry
{
std::string family_name;
std::string given_name;
};
auto as_tuple(const name_entry& e)
{
return std::tie(e.family_name, e.given_name);
}
bool operator<(const name_entry& x, const name_entry& y)
{
return as_tuple(x) < as_tuple(y);
}
bool operator<(const name_entry& x, const std::string& y)
{
return x.family_name<y;
}
bool operator<(const std::string& x, const name_entry& y)
{
return x<y.family_name;
}
int main()
{
std::set<name_entry, std::less<>> names;
}
发明异构比较是为了找到满足部分比较的包含对象,比如发现某人有一个姓氏。
另一方面, operator[]
将构造value_type
如果找不到key
,则必须在此操作中应用严格的弱排序,因此不能应用异构比较