繁体   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