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