研究了一下后,我发现C++11存在一个缺陷,这个缺陷与要求类型可移动/可复制的分配器有关。我确定这是问题的原因,但我对删除和未声明移动语义之间的行为感到困惑。
我有以下代码,在MSVC12和Clang上都无法编译:
#include <vector>
class Copyable
{
public:
Copyable() = default;
Copyable(Copyable const& other)
: m_int(other.m_int)
{}
Copyable& operator= (Copyable const& other)
{
m_int = other.m_int;
return *this;
}
Copyable(Copyable&&) = delete;
Copyable& operator= (Copyable&&) = delete;
private:
int m_int = 100;
};
int main()
{
std::vector<Copyable> objects;
objects.push_back(Copyable{});
}
在 MSVC 上编译失败,错误信息如下:
xmemory0(600): error C2280: 'Copyable::Copyable(Copyable &&)' : 尝试引用已删除的函数
在 Clang 上也有问题(在线样例):
new_allocator.h:120:23: error: 调用已删除的构造函数 'Copyable'
两种情况下,当我删除了显式删除的移动构造/赋值方法后,代码可以编译。据我所知,当你声明复制构造/赋值方法时,编译器不会隐式声明相应的移动成员。所以它们仍然被有效地删除,是吗?为什么当我删除显式删除的移动构造/赋值函数时,代码可以编译?
通常有哪些好的解决方案来解决这个 C++11 的缺陷?我不希望我的对象可移动(但可复制)。