我有一个复制/移动探测类:为什么std :: vector在初始化时强制复制?
#include <iostream>
struct A
{
A()
{
std::cout << "Creating A" << std::endl;
}
~A() noexcept
{
std::cout << "Deleting A" << std::endl;
}
A(const A &)
{
std::cout << "Copying A" << std::endl;
}
A(A &&) noexcept
{
std::cout << "Moving A" << std::endl;
}
A &operator=(const A &)
{
std::cout << "Copy-assigning A" << std::endl;
return *this;
}
A &operator=(A &&) noexcept
{
std::cout << "Move-assigning A" << std::endl;
return *this;
}
};
而且我发现,运行:
#include <vector>
int main(int, char **)
{
std::vector<A> v { A() };
}
产生以下输出:
Creating A
Copying A
Deleting A
Deleting A
为什么不会初始化只是移动对象?我知道std::vector
可能会创建undesired copies on resize,但正如你所看到的,添加noexcept
在这里没有帮助(此外,我不认为调整大小导致副本适用于初始化的原因)。
如果我不是做到以下几点:
std::vector<A> v;
v.push_back(A());
我没有得到副本。
经GCC 5.4和Clang 3.8测试。
这是因为正在使用'std :: initializer_list'构造函数。这种类型的语义是不幸的。 – StoryTeller
本问答解释了这种情况,并提供了一些解决方法:https://stackoverflow.com/questions/8468774/can-i-list-initialize-a-vector-of-move-only-type –
@StoryTeller @MM I看,所以问题不是'std :: vector',而是'std :: initializer_list',显然不能转发右值引用?如果有人可以请发表正确的答案,我会接受。 – jdehesa