2016-07-26 81 views
2

请参见下面的代码:初始化列表在C++中

std::vector<int> v1{1, 2, 3}; 
std::vector<int> v2 = {1, 2, 3}; 

我的问题是:

  1. 是两者之间有什么区别?我知道第一个必须是列表初始化,但第二个怎么样?

  2. 由于不存在第二个是分配的迹象,这让我觉得,编译器将使用std::initializer_list首先创建一个临时vector,然后用它的拷贝构造函数来复制vector临时到v2。这是事实吗?

回答

8

这两个(direct-list-initialization vs copy-list-initialization)在这种情况下是完全一样的。没有构建临时的std::vector,并且没有调用std::vector::operator=。等号是初始化语法的一部分。

会有区别,如果std::vector's constructor overload no. 7被标记explicit,在这种情况下,任何副本初始化失败,但是这将是在标准库的设计缺陷。

+0

因此,两者都属于列表初始化,它们与复制初始化没有关联,对吗? – zhangzhimin

+0

* copy-list-initialization *是根据* copy-initialization *定义的。我已经使用* copy-initialization *来推广一下。 – LogicStuff

8

它们都是list initialization(自C++ 11以来),第一个是直接列表初始化,第二个是复制列表初始化。

  1. 这两者有什么区别吗?

对于直接列表初始化显式和非显式的构造将被考虑,而副本列表初始化唯一的非显式的构造可能会被调用。对于这种情况(即std::vector),实际结果是相同的。

  • 因为存在用于第二一个分配标志,这让我认为编译器将使用initializer_list首先创建一个临时载体,然后使用它的拷贝构造来复制临时向量为v2。这是事实吗?
  • 即使复制列表初始化号,对象会被适当的构造直接构造。对于这种情况,将创建一个临时std::initializer_list<int>,然后调用std::vector::vector(std::initializer_list<T>, const Allocator& = Allocator())构造v2

    +0

    有趣的是,在C++ 17中,如果使用auto和仅包含一个元素的列表,它可能会有所不同。 – EFenix

    +1

    @AntonioGarrido不,它不会。 'auto v = {1}'永远不会推导出'std :: vector'。事实上,现在它会推导出'int'而不是'std :: initializer_list',但与关于'std :: vector'的讨论完全无关。 – bolov

    +1

    @AntonioGarrido如果您想将C++ 17和auto引入讨论,可能会有点相关,您可以编写'auto v = vector {1,2,3}'(构造函数的模板扣除) – bolov