两者之间有什么区别
std::vector<int> v;
和
std::vector<int> v = std::vector<int>();
直觉上,我永远不会使用第二个版本,但是我不确定是否有任何区别。在我看来,第二行只是一个默认的构造函数,它构建一个临时对象,然后由移动分配运算符将其移动。
我想知道第二行是否在某种程度上不等于
std::vector<int> v = *(new std::vector<int>());
因此导致向量本身在堆上(动态分配)。如果是这样,那么在大多数情况下,第一行可能是首选。
这些代码行有何不同?
答案 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 );
std::vector<int> v = { 1,2,3,4,5 };
std::vector<int> v{ 1,2,3,4,5 };
以下是std::vector
constructors的列表。