2016-12-28 117 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 []'沒有被擴展同樣的方式,不是對錯誤的解釋 –

相關問題