为什么'std :: vector< int> b {2};'创建1元素向量,而不是2元素向量? [英] Why does 'std::vector<int> b{2};' create a 1-element vector, and not a 2-element one?

查看:171
本文介绍了为什么'std :: vector< int> b {2};'创建1元素向量,而不是2元素向量?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在过去几天一直在用C ++ 11玩游戏,我想出了一些奇怪的东西。

I've been playing around with C++11 for the past few days, and I came up with something strange.

如果我想统一初始化int:

If I want to uniformly initialize an int:

int a{5};

但是如果我对std :: vector做同样的事情:

But if I do the same thing to a std::vector:

std::vector<int> b{2};

不构造两个元素数组,而是一个具有值为2的元素的数组。它似乎得到的效果,需要更明确的它:

Does not construct a two element array, but rather an array with one element of value two. It seems like to get that effect one would need to be more explicit about it:

std::vector<int> c{{2}};
std::vector<int> d = {2};

但不像b的声明 - 这似乎不一致。我已经看到一些其他的东西,以同样的效果。我要问的是 - 这是在最终的C ++ 11标准的行为,还是只是在早期实施的草案?如果是,标准委员会为什么包括这种行为?它似乎它打败了统一初始化的整个目的,因为必须记住哪些类有初始化列表构造函数,并使用old()语法,而不是{}只有那些类。或者一个人完全放弃了统一的初始化。

But not like the declaration of b - this seems inconsistent. I have seen some other stuff to the same effect. What I'm asking - is this behavior in the final C++11 standard, or is it just in a draft that was implemented early? If so, why did the standards committee include this behavior? It seems like it defeats the whole purpose of uniform initialization, as one has to remember which classes have initializer list constructors, and to use the old () syntax instead of {} with just those classes. Or one forgoes uniform initialization altogether.

这似乎是一个大的gotcha。

This seems like a big "gotcha". But there might be advantages to it that I am not aware of.

编辑:此代码:

#include <iostream>
#include <vector>

int main() {
    std::vector<int> a{2};
    for (auto x: a) {
        std::cout << x << std::endl;
    }
    return 0;
}

在gcc上输出24.6.2

outputs "2" on gcc 4.6.2

推荐答案

是的,这种行为是根据§13.3.1.7通过列表初始化初始化

Yes, this behaviour is intended, according to §13.3.1.7 Initialization by list-initialization

当非聚合类类型T的对象被列表初始化为
(8.5.4)时,重载解析选择两个阶段的构造函数:

When objects of non-aggregate class type T are list-initialized (8.5.4), overload resolution selects the constructor in two phases:

- 最初,候选函数是 T 类的初始化列表
构造函数(8.5.4),参数列表由
初始化列表作为单个参数。

— Initially, the candidate functions are the initializer-list constructors (8.5.4) of the class T and the argument list consists of the initializer list as a single argument.

- 如果找不到可行的
initializer-list构造函数,则重载分辨率为
,其中候选函数都是 T 类的
构造函数,参数列表由初始化器列表的
元素组成。

— If no viable initializer-list constructor is found, overload resolution is performed again, where the candidate functions are all the constructors of the class T and the argument list consists of the elements of the initializer list.

对于统一初始化的整体目的...统一初始化是一个营销术语,不是一个很好的描述。该标准具有所有常见的初始化形式列表初始化,但没有统一初始化。列表初始化并不意味着是初始化的最终形式,它只是实用程序带中的另一个工具。

As to "the whole purpose of uniform intialization"... "Uniform initialization" is a marketing term, and not a very good description. The standard has all the usual forms of initialization plus list-initialization, but no "uniform initialization". List initialization is not meant to be the ultimate form of initialization, it's just another tool in the utility belt.

这篇关于为什么'std :: vector&lt; int&gt; b {2};'创建1元素向量,而不是2元素向量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆