2016-12-28 71 views
2
#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);没问题。为什么std :: map不总是允许兼容类型作为其键类型?

但是,为什么不是coll[key] = 0;好吗?

+1

应用,因为[]没有得到更多重载在14,不像发现...? – deviantfan

+1

'运算符[]'也没有找到时插入 – Danh

+1

@deviantfan,为什么不重载[]? – xmllmx

回答

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,有必要采取严格的弱序与此操作,从而cannt异构比较

+0

我猜那些'operator()'应该是'operator <'?无论如何,理智的操作符<'实现,而不是手动比较:'返回std :: tie(x.family_name,x.given_name) ildjarn

+0

@ildjarn yes,我没有太多改变,从那篇论文中复制出来。现在将编辑。关于'std :: tie',我知道它更好,就像我说的那样,我从该文件复制过来 – Danh

4

coll.find(key)只需要key可比与实际键类型以及std::string_viewstd::string媲美。然而,为了能够将key插入到coll中,key需要是可转换的std::string,它不是(隐含地,无论如何)。

+2

我相信OP是问为什么'find'被重载来推导类型而'operator []'没有被扩展同样的方式,不是对错误的解释 –

相关问题