直接列表初始化和复制列表初始化之间的差异

Lon*_*ner 11 c++ initialization c++11 c++14 c++17

我想知道std::vectorC++ 11及更高版本中的以下两种初始化是否有任何区别.

std::vector<int> v1 {1, 2, 3, 4, 5};
std::vector<int> v2 = {1, 2, 3, 4, 5};
Run Code Online (Sandbox Code Playgroud)

这是一个完整的代码示例,工作正常.

#include <iostream>
#include <vector>

int main()
{
    std::vector<int> v1 {1, 2, 3, 4, 5};
    std::vector<int> v2 = {1, 2, 3, 4, 5};

    std::cout << v1.size() << '\n';
    std::cout << v2.size() << '\n';
}
Run Code Online (Sandbox Code Playgroud)

我看到两个初始化都会导致相同的结果.

http://en.cppreference.com/w/cpp/container/vector上的示例使用第二种,这让我想到这种初始化是否有任何优势.

一般来说,我想知道一个初始化是否具有相对于另一个的特定技术优势,或者如果一个初始化被认为是最佳实践而另一个不是,如果是,为什么.

特别是,我关心的是复制列表初始化是否由于临时对象和复制而产生额外的开销?

Nic*_*las 13

列表初始化被非正式地称为"统一初始化",因为无论您如何调用它,其含义和行为都是相同的.

因此,直接列表初始化和复制列表初始化的行为之间只有一个区别:如果列表初始化会调用标记的构造函数explicit,那么如果列表初始化表单是复制,则存在编译错误 -列表初始化.这是唯一的区别.

[dcl.list.init]解释了direct-list和copy-list之间的语法差异.也就是说,它描述了哪种形式的列表初始化是直接与复制.但它从未定义两者之间的任何功能差异.

定义行为差异的标准的唯一部分是[over.match.list]/1:

在copy-list-initialization中,如果explicit选择了构造函数,则初始化是错误的.

这是重载分辨率的函数.

由于标准没有定义任何行为差异,如果编译器决定在它们之间强加一些功能差异,我会非常惊讶.

  • 您错过了http://eel.is/c++draft/dcl.init.list#3.8和一对"(通过复制初始化进行复制列表初始化,或通过直接初始化进行直接列表初始化) )"案件. (2认同)

Fra*_*ank 6

我非常喜欢复制列表初始化(特别是在这种情况下std::vector),因为std::vector当只有一个或两个元素时,直接列表初始化与显式构造函数非常相似.

std::vector<int> x(2);
// is very different from
std::vector<int> x{2};
Run Code Online (Sandbox Code Playgroud)

明确我正在为向量分配初始值而不用值配置它的事实不容易被误读.

  • 我不确定这与问题有什么关系 (2认同)