为什么当我用大括号初始化 std::vector 时
std::vector<TS> vec {ts1, ts2};
编译器调用两次复制构造函数运算符?另一方面 - 使用push_back它只调用一次。
#include <iostream>
#include <vector>
using namespace std;
struct TS{
TS(){
cout<<"default constructor\n";
}
TS(const TS &other) {
cout<<"Copy constructor\n";
}
TS(TS &&other) noexcept{
cout<<"Move constructor\n";
}
TS& operator=(TS const& other)
{
cout<<"Copy assigment\n";
return *this;
}
TS& operator=(TS const&& other) noexcept
{
cout<<"Move assigment\n";
return *this;
}
~TS(){
cout<<"destructor\n";
}
};
int main() {
TS ts1;
TS ts2;
cout<<"-----------------------------------------\n";
std::vector<TS> vec {ts1, ts2};
//vec.push_back(ts1);
//vec = {ts1, ts2};
cout<<"-----------------------------------------\n";
return 0;
}
http://ideone.com/qcPG7X
据我了解,initializer_list
通过常量引用传递所有内容。可能不安全move
从一。这initializer_list
的构造函数vector
将复制每个元素。
以下是一些链接:初始化列表和移动语义
不,这不会按预期工作;您仍然会得到副本。我很漂亮
对此感到惊讶,因为我认为初始化器列表的存在是为了
保留一系列临时对象,直到它们被移动为止。
初始值设定项列表的开始和结束返回 const T *,因此结果
代码中的移动是 T const && — 一个不可变的右值引用。这样的
无法有意义地移动表达式。它将绑定到一个
T const & 类型的函数参数,因为右值确实绑定到 const
左值引用,您仍然会看到复制语义。
移动初始值设定项列表的元素是否安全?
initializer_list 只提供对其元素的 const 访问。你可以
使用 const_cast 使该代码编译,但随后移动可能会结束
未定义的行为(如果initializer_list的元素
是真正的常量)。所以,不,这样做是不安全的。有
如果您确实需要的话,可以找到解决方法。
我可以列表初始化仅移动类型的向量吗?
18.9 的概要已经相当清楚了
初始化列表的元素总是通过
const 引用。不幸的是,似乎没有任何办法
在当前的初始值设定项列表元素中使用 move-semantic
语言的修订。
有关 std::initializer_list 设计的问题
来自 C++ 标准第 18.9 节:
类型initializer_list的对象提供对const E类型的对象数组的访问。 [注:一对指针或一个指针加
长度是初始化器列表的明显表示。
initializer_list 用于实现指定的初始值设定项列表
在 8.5.4 中。复制初始值设定项列表不会复制底层
元素。 ——尾注]
我认为大多数这些事情的原因是
std::initializer_list 实际上不是一个容器。它没有
值语义,它有指针语义。显而易见的是
引用的最后一部分:复制初始值设定项列表不会
复制底层元素。因为它们的目的只是为了
初始化事物的目的,我认为这并不令人惊讶
您无法获得更强大的容器的所有优点,例如
元组。
如果我对最后一部分的理解正确的话,这意味着需要两套副本,因为initializer_list
不复制底层元素。(前面的引用仅在您尝试使用initializer_list
无需复制元素。)
std::initializer_list 的底层结构是什么?
不,您不能从初始化列表的元素中移动,因为
初始化列表的元素应该是不可变的(参见
上面引用的段落的第一句话)。这也是原因
为什么只有 const 限定的成员函数才能让您访问
元素。
如果你愿意,你可以使用emplace_back
:
vec.emplace_back(TS());
vec.emplace_back(TS());
vec.push_back(std::move(ts1));
vec.push_back(std::move(ts2));
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)