簡體   English   中英

為什么第二次初始化工作而第一個由於“元素類型不匹配”而失敗?

[英]Why the second initialization work while the first one fail because of the "element type does not match"?

在 C++ 入門中,將一個容器初始化為另一個容器的副本。

只要可以將我們正在復制的元素轉換為我們正在初始化的容器的元素類型,新容器和原始容器中的元素類型就可以不同。

例如:

vector<const char*> articles = {"a", "an", "the"};
vector<string> words(articles) ; //error:element types must match
forward_list<string> words(articles.begin(), articles.end()); // ok, convert const char* to string

我的問題是為什么第二個初始化工作而第一個因為元素類型不匹配而失敗?

第一行使用與元素類型 (const char*) 相同類型的 initializer_list 調用構造函數。 像這樣:

vector<T>(initializer_list<T> t ) {....} 

--> 好的!

第二個是復制構造函數調用,它只為相同的元素類型定義。

vector<T>(const& vector<T> t) {...}

你所做的是這樣的:

vector<string>(const& vector<const char*> t){..}

--> 哪個不存在!

第一行執行 復制列表初始化(參見initializer_list構造函數)。

第二行沒有匹配的構造函數,因為類型不匹配(它不能調用復制構造函數)。

第三行改為使用迭代器范圍構造函數,該構造函數用於構造元素並具有可行的const char*string轉換以供使用。

我的問題是為什么第二次初始化工作而第一個失敗

你正在構建一個東西 這不是靠魔法完成的,它只需要調用something的構造函數之一。 任何無法匹配其中一個構造函數的表達式都無法編譯。


所以,讓我們首先考慮

vector<const char*> articles = {"a", "an", "the"};
vector<string> words(articles);

現在,我們需要一些對這個表達式有意義的std::vector構造函數。 它們在此處列出,唯一接近匹配的是數字 5 和 6(在撰寫本文時 - 它們是復制和移動構造函數)。

因為我們沒有使用std::move或以其他方式直接處理右值引用,所以移動構造函數已失效,所以讓我們看看復制構造函數:

vector<string>::vector<string>(const vector<string> &other);

請注意,這不是模板化以采用任何參數類型,或采用任何類型的向量:它只匹配對完全相同類型的向量的 const 引用。 即使const char *可以隱式轉換為std::string ,類型vector<string>仍然與vector<const char *> 因此,沒有構造函數與給定的參數類型匹配。


然后,考慮

forward_list<string> words(articles.begin(), articles.end());

此處列出std::forward_list構造函數。 注意編號 4:

template< class InputIt >
forward_list(InputIt first, InputIt last, 
             const Allocator& alloc = Allocator() );

首先,這是在迭代器類型上模板化的,因此傳遞vector<string>::iteratorvector<const char *>::iterator或任何問題都沒有問題。 其次,從const char *std::string的轉換足以讓這個重載在被選中后實際編譯。


現在,有幾個注意事項:

  1. 您提到了explicit關鍵字:這只是防止將單參數構造函數用作隱式轉換。 不過,它不會影響更高的類型:即使允許string::string(const char *)作為隱式轉換,也不會使vector<const char *>轉換為vector<string> 這仍然必須通過vector的構造函數之一。

  2. 我們在這里主要討論如何選擇重載(在本例中為重載構造函數)。 完全有可能編譯器可以選擇重載,然后仍然無法編譯。 例如,使用第二個迭代器范圍構造函數,其中迭代器指向一些不兼容(甚至不能顯式轉換)的類型。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM