vector <int> v;`和`vector <int> v = vector <int>();`

时间:2019-03-01 03:15:06

标签: c++ constructor initialization

两者之间有什么区别

std::vector<int> v;

std::vector<int> v = std::vector<int>();

直觉上,我永远不会使用第二个版本,但是我不确定是否有任何区别。在我看来,第二行只是一个默认的构造函数,它构建一个临时对象,然后由移动分配运算符将其移动。

我想知道第二行是否在某种程度上不等于

std::vector<int> v = *(new std::vector<int>()); 

因此导致向量本身在堆上(动态分配)。如果是这样,那么在大多数情况下,第一行可能是首选。

这些代码行有何不同?

3 个答案:

答案 0 :(得分:40)

从C ++ 17开始,没有任何区别。

在一个特殊的用例中,QNetworkReply *reply = qobject_cast<QNetworkReply*>(sender()); QString strReply = (QString)reply->readAll(); QJsonDocument jsonResponse = QJsonDocument::fromJson(strReply.toUtf8()); QJsonObject jsonObject = jsonResponse.object(); model->exchangeArray = jsonObject["exchanges"].toArray(); model->updateData(); reply->deleteLater(); 初始化语法非常有用(尽管不是默认构造):当一个人想为类的emit layoutChanged(); 成员提供“计数,值”初始化器时直接在类的定义中:

std::vector = std::vector

类内初始化程序仅支持std::vector<int>struct S { std::vector<int> v; // Want to supply `(5, 42)` initializer here. How? }; 语法,这意味着我们不能只说

=

如果我们使用

{}

编译器会将其解释为值列表,而不是我们想要的“计数,值”对。

所以,一种正确的方法是

struct S {
  std::vector<int> v(5, 42); // Error
};

答案 1 :(得分:22)

第一个是default initialization,第二个是copy initialization;效果是相同的,即通过v的默认构造函数初始化对象std::vector

对于std::vector<int> v = std::vector<int>();,从概念上讲,它将构造一个临时std::vector,然后使用它来移动构造对象v(请注意,这里没有分配)。根据{{​​3}}(从C ++ 17开始保证),它将仅调用默认构造函数直接初始化v

  

在以下情况下,要求编译器省略   复制和移动类对象的构造,即使复制/移动   构造函数和析构函数具有明显的副作用。的   将对象直接构建到它们将要存储的存储中   否则将其复制/移动到。复制/移动构造函数不需要   存在或可访问,因为语言规则确保没有复制/移动   操作甚至在概念上都会发生:

     
      
  • 在初始化变量时,使用初始化表达式   是与该类类型相同的prvalue(忽略cv限定)   变量类型:

    T x = T(T(f())); // only one call to default constructor of T, to initialize x
    
  •   

(在C ++ 17之前,复制省略是一种优化。)

  

这是一种优化:即使发生并且未调用copy / move(由于C ++ 11)构造函数,它也必须存在并且可以访问(好像根本没有优化发生),

BTW:对于这两种情况,都不会通过std::vector表达式来构造具有动态存储持续时间的new对象(包括潜在的临时对象)。

答案 2 :(得分:-1)

您曾问过:

  

两者之间有什么区别

std::vector<int> v;
     

std::vector<int> v = std::vector<int>();
     

正如其他人从C ++ 17开始所说的那样,基本上没有区别。现在,关于要使用哪一个的偏好,我建议如下:

  • 如果您要创建一个空的向量以待稍后填写,则第一个版本是更理想的选择。
  • 如果您要构造一个带有默认值作为其成员之一或指定计数的向量,则将使用较新的版本。
  • 请注意,以下两个是不同的构造函数:
    • std::vector<int> v = std::vector<int>();
    • 与以下构造器不同:
    • std::vector<int> v = std::vector<int>( 3, 10 );
    • 构造函数的2 nd 版本是重载的构造函数。
  • 否则,如果要从一组数字构造一个向量,则可以使用以下选项:

以下是std::vector constructors的列表。