簡體   English   中英

為什么向量的多參數構造函數采用未標記為“顯式”的構造參數?

[英]Why are vector's multi-argument constructors taking construction parameters not marked "explicit"?

我在標准 C++ 庫中觀察到以下向量構造函數

explicit vector(size_type n);
vector(size_type n, const T& value, const Allocator& = Allocator());

第二個構造函數沒有標記為explicit的原因嗎? 這編譯,讓我感覺不好

void f(vector<string>);

int main() {
  f({10, "foo"});
}

雖然如果我省略"foo" ,它不會編譯,這就是我將 int 和字符串的對(復合)值傳遞給需要字符串向量的 function 時所期望的。

我想知道在創建臨時對象時期望{... }始終代表容器元素列表是否合法。 這似乎是你的假設。 IMO需要將單參數構造函數聲明為explicit以避免意外的轉換序列或無意義的分配,例如:

vector<int> x = 3;

另一方面,對於雙參數版本,在創建臨時變量時調用此構造函數的唯一方法是使用花括號,並且程序員很清楚他在其中放入了什么。 例如,我很清楚10"hello"並不是要表示容器元素的列表,因為10不是字符串。

如果我真的想傳入一個初始化為"hello"的 10 個元素的向量,我會因為不得不寫f(vector(10, "hello"))而不是只寫f({10, "hello"}) .

所以總結一下:雖然需要將單參數構造函數聲明為explicit ,但我相信這對於雙參數值不是強制性的,因為並非一對花括號內的所有內容都應解釋為容器元素。

雖然如果我省略“foo”,它不會編譯,這就是我將 int 和字符串的一對(復合)值傳遞給需要字符串向量的 function 時所期望的。

不,您沒有傳遞一對 int 和一個字符串,而是創建了一個大小為 10 的向量,其中包含諸如“foo”之類的字符串內容。 它沒有錯。 我可以想出一些情況,從一開始就創建一個包含相等字符串的向量可能很有用

當我將 int 和字符串的一對(復合)值傳遞給需要字符串向量的 function 時,這就是我所期望的。

嗯,有你的問題。

{...}不是“復合值”。 它不是一個列表。 它說,“使用這些值初始化 object”。 如果所討論的 object 是一個聚合,它將使用聚合初始化。 如果所討論的 object 是非聚合類型,它將根據類型的匹配構造函數和 C++11 中花括號初始化列表的各種規則來選擇要調用的構造函數。

您不應將{10, "foo"}視為兩個值的列表。 它是一個包含兩個值的初始化程序。 它可以與std::pair<int, const char *>等一起使用。

std::vector的構造函數不明確的原因正是為了允許這種構造。 單參數構造函數是顯式的,否則,隱式轉換規則將允許這樣做:

std::vector<T> v = 5; //???

或者,更重要的是:

void Foo(const std::vector<T> &v);

Foo(5); //???

我們不希望整數隱式轉換為std::vector 但是,當您使用初始化程序時,允許更廣泛的“隱式”轉換更合理,因為您可以在那里看到{}語法。

對於單參數情況,不清楚用戶的意思。 使用 {} 語法,用戶的意思清楚:初始化 object。

Foo({10, "foo"}); //Initializes the first argument given the values.

暫無
暫無

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

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