[英]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.