C++ 不可移动不可复制对象向量的移动赋值不编译

C++ 不可移动不可复制对象向量的移动赋值不编译,c++,c++11,visual-studio-2013,language-lawyer,move-semantics,C++,C++11,Visual Studio 2013,Language Lawyer,Move Semantics,以下代码不使用Visual Studio 2013编译: #include <vector> struct X { X() = default; X(const X&) = delete; X& operator=(const X&) = delete; X(X&&) = delete; X& operator=(X&&) = delete; ~X() = default

以下代码不使用Visual Studio 2013编译:

#include <vector>

struct X {
    X() = default;
    X(const X&) = delete;
    X& operator=(const X&) = delete;
    X(X&&) = delete;
    X& operator=(X&&) = delete;
    ~X() = default;
};

void foo()
{
    std::vector<X> v;
    std::vector<X> w;
    w = std::move(v);
}
那对我来说毫无意义。移动
向量
不需要
X
的移动构造函数。这是一个编译器错误,还是我遗漏了什么

以下是完整的错误消息:

C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\xmemory0(600): error C2280: 'X::X(X &&)' : attempting to reference a deleted function
    Test.cpp(9) : see declaration of 'X::X'
    C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\xmemory0(723) : see reference to function template instantiation 'void std::allocator<_Ty>::construct<_Objty,_Ty>(_Objty *,_Ty &&)' being compiled
    with
    [
        _Ty=X
    ,   _Objty=X
    ]
    C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\xmemory0(723) : see reference to function template instantiation 'void std::allocator<_Ty>::construct<_Objty,_Ty>(_Objty *,_Ty &&)' being compiled
    with
    [
        _Ty=X
    ,   _Objty=X
    ]
    C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\xmemory0(872) : see reference to function template instantiation 'void std::allocator_traits<_Alloc>::construct<_Ty,_Ty>(std::allocator<_Ty> &,_Objty *,_Ty &&)' being compiled
    with
    [
        _Alloc=std::allocator<X>
    ,   _Ty=X
    ,   _Objty=X
    ]
    C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\xmemory0(872) : see reference to function template instantiation 'void std::allocator_traits<_Alloc>::construct<_Ty,_Ty>(std::allocator<_Ty> &,_Objty *,_Ty &&)' being compiled
    with
    [
        _Alloc=std::allocator<X>
    ,   _Ty=X
    ,   _Objty=X
    ]
    C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\xmemory(378) : see reference to function template instantiation 'void std::_Wrap_alloc<std::allocator<_Ty>>::construct<X,X>(_Ty *,X &&)' being compiled
    with
    [
        _Ty=X
    ]
    C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\xmemory(378) : see reference to function template instantiation 'void std::_Wrap_alloc<std::allocator<_Ty>>::construct<X,X>(_Ty *,X &&)' being compiled
    with
    [
        _Ty=X
    ]
    C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\xmemory(416) : see reference to function template instantiation '_FwdIt std::_Uninit_copy<_InIt,_FwdIt,std::allocator<_Ty>>(_InIt,_InIt,_FwdIt,std::_Wrap_alloc<std::allocator<_Ty>> &,std::_Nonscalar_ptr_iterator_tag)' being compiled
    with
    [
        _FwdIt=X *
    ,   _InIt=std::move_iterator<std::_Vector_iterator<std::_Vector_val<std::_Simple_types<X>>>>
    ,   _Ty=X
    ]
    C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\xmemory(427) : see reference to function template instantiation '_FwdIt std::_Uninit_copy<_Iter,X,_Alloc>(_InIt,_InIt,_FwdIt,_Alloc &)' being compiled
    with
    [
        _FwdIt=X *
    ,   _Iter=std::move_iterator<std::_Vector_iterator<std::_Vector_val<std::_Simple_types<X>>>>
    ,   _Alloc=std::_Wrap_alloc<std::allocator<X>>
    ,   _InIt=std::move_iterator<std::_Vector_iterator<std::_Vector_val<std::_Simple_types<X>>>>
    ]
    C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\vector(1640) : see reference to function template instantiation '_FwdIt std::_Uninitialized_copy<_Iter,X*,std::_Wrap_alloc<std::allocator<_Ty>>>(_InIt,_InIt,_FwdIt,_Alloc &)' being compiled
    with
    [
        _FwdIt=X *
    ,   _Iter=std::move_iterator<std::_Vector_iterator<std::_Vector_val<std::_Simple_types<X>>>>
    ,   _Ty=X
    ,   _InIt=std::move_iterator<std::_Vector_iterator<std::_Vector_val<std::_Simple_types<X>>>>
    ,   _Alloc=std::_Wrap_alloc<std::allocator<X>>
    ]
    C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\vector(789) : see reference to function template instantiation 'X *std::vector<X,std::allocator<_Ty>>::_Ucopy<_Iter>(_Iter,_Iter,X *)' being compiled
    with
    [
        _Ty=X
    ,   _Iter=std::move_iterator<std::_Vector_iterator<std::_Vector_val<std::_Simple_types<X>>>>
    ]
    C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\vector(789) : see reference to function template instantiation 'X *std::vector<X,std::allocator<_Ty>>::_Ucopy<_Iter>(_Iter,_Iter,X *)' being compiled
    with
    [
        _Ty=X
    ,   _Iter=std::move_iterator<std::_Vector_iterator<std::_Vector_val<std::_Simple_types<X>>>>
    ]
    C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\vector(766) : see reference to function template instantiation 'void std::vector<X,std::allocator<_Ty>>::_Construct<_Iter>(_Iter,_Iter,std::forward_iterator_tag)' being compiled
    with
    [
        _Ty=X
    ,   _Iter=std::move_iterator<std::_Vector_iterator<std::_Vector_val<std::_Simple_types<X>>>>
    ]
    C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\vector(766) : see reference to function template instantiation 'void std::vector<X,std::allocator<_Ty>>::_Construct<_Iter>(_Iter,_Iter,std::forward_iterator_tag)' being compiled
    with
    [
        _Ty=X
    ,   _Iter=std::move_iterator<std::_Vector_iterator<std::_Vector_val<std::_Simple_types<X>>>>
    ]
    C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\vector(854) : see reference to function template instantiation 'void std::vector<X,std::allocator<_Ty>>::_Construct<std::move_iterator<std::_Vector_iterator<std::_Vector_val<std::_Simple_types<X>>>>>(_Iter,_Iter)' being compiled
    with
    [
        _Ty=X
    ,   _Iter=std::move_iterator<std::_Vector_iterator<std::_Vector_val<std::_Simple_types<X>>>>
    ]
    C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\vector(854) : see reference to function template instantiation 'void std::vector<X,std::allocator<_Ty>>::_Construct<std::move_iterator<std::_Vector_iterator<std::_Vector_val<std::_Simple_types<X>>>>>(_Iter,_Iter)' being compiled
    with
    [
        _Ty=X
    ,   _Iter=std::move_iterator<std::_Vector_iterator<std::_Vector_val<std::_Simple_types<X>>>>
    ]
    C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\vector(849) : while compiling class template member function 'void std::vector<X,std::allocator<_Ty>>::_Assign_rv(std::vector<_Ty,std::allocator<_Ty>> &&,std::false_type)'
    with
    [
        _Ty=X
    ]
    C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\vector(860) : see reference to function template instantiation 'void std::vector<X,std::allocator<_Ty>>::_Assign_rv(std::vector<_Ty,std::allocator<_Ty>> &&,std::false_type)' being compiled
    with
    [
        _Ty=X
    ]
    Test.cpp(16) : see reference to class template instantiation 'std::vector<X,std::allocator<_Ty>>' being compiled
    with
    [
        _Ty=X
    ]
C:\ProgramFiles(x86)\Microsoft Visual Studio 12.0\VC\include\xmemory0(600):错误C2280:'X::X(X&&)':尝试引用已删除的函数
Test.cpp(9):参见“X::X”的声明
C:\Program Files(x86)\Microsoft Visual Studio 12.0\VC\include\xmemory0(723):请参阅正在编译的函数模板实例化“void std::allocator::construct(_Objty*,_Ty&)”
具有
[
_Ty=X
,_Objty=X
]
C:\Program Files(x86)\Microsoft Visual Studio 12.0\VC\include\xmemory0(723):请参阅正在编译的函数模板实例化“void std::allocator::construct(_Objty*,_Ty&)”
具有
[
_Ty=X
,_Objty=X
]
C:\ProgramFiles(x86)\Microsoft Visual Studio 12.0\VC\include\xmemory0(872):请参阅正在编译的函数模板实例化“void std::allocator_traits::construct(std::allocator&、_Objty*、_Ty&)”的参考
具有
[
_Alloc=std::分配器
,_Ty=X
,_Objty=X
]
C:\ProgramFiles(x86)\Microsoft Visual Studio 12.0\VC\include\xmemory0(872):请参阅正在编译的函数模板实例化“void std::allocator_traits::construct(std::allocator&、_Objty*、_Ty&)”的参考
具有
[
_Alloc=std::分配器
,_Ty=X
,_Objty=X
]
C:\ProgramFiles(x86)\Microsoft Visual Studio 12.0\VC\include\xmemory(378):请参阅正在编译的函数模板实例化“void std::_Wrap\u alloc::construct(_Ty*,X&)”的参考
具有
[
_Ty=X
]
C:\ProgramFiles(x86)\Microsoft Visual Studio 12.0\VC\include\xmemory(378):请参阅正在编译的函数模板实例化“void std::_Wrap\u alloc::construct(_Ty*,X&)”的参考
具有
[
_Ty=X
]
C:\ProgramFiles(x86)\Microsoft Visual Studio 12.0\VC\include\xmemory(416):请参阅正在编译的函数模板实例化“\u FwdIt std:\u Uninit\u copy(\u InIt,\u InIt,\u FwdIt,std:\u Wrap\u alloc&,std:\u Nonscalar\u ptr\u iterator\u tag)”
具有
[
_FwdIt=X*
,_InIt=std::move_迭代器
,_Ty=X
]
C:\Program Files(x86)\Microsoft Visual Studio 12.0\VC\include\xmemory(427):请参阅正在编译的函数模板实例化“\u FwdIt std::\u Uninit\u copy(\u InIt,\u FwdIt,\u Alloc&)”的参考
具有
[
_FwdIt=X*
,Iter=std::move\u迭代器
,_Alloc=std::_Wrap_Alloc
,_InIt=std::move_迭代器
]
C:\ProgramFiles(x86)\Microsoft Visual Studio 12.0\VC\include\vector(1640):请参阅正在编译的函数模板实例化“\u FwdIt std::\u未初始化的\u副本(\u InIt,\u FwdIt,\u Alloc&)”
具有
[
_FwdIt=X*
,Iter=std::move\u迭代器
,_Ty=X
,_InIt=std::move_迭代器
,_Alloc=std::_Wrap_Alloc
]
C:\ProgramFiles(x86)\Microsoft Visual Studio 12.0\VC\include\vector(789):请参阅正在编译的函数模板实例化“X*std::vector::\u uUCopy(\u Iter,\u Iter,X*)”
具有
[
_Ty=X
,Iter=std::move\u迭代器
]
C:\ProgramFiles(x86)\Microsoft Visual Studio 12.0\VC\include\vector(789):请参阅正在编译的函数模板实例化“X*std::vector::\u uUCopy(\u Iter,\u Iter,X*)”
具有
[
_Ty=X
,Iter=std::move\u迭代器
]
C:\Program Files(x86)\Microsoft Visual Studio 12.0\VC\include\vector(766):请参阅正在编译的函数模板实例化“void std::vector:::_Construct(_Iter,_Iter,std::forward_iterator_tag)”
具有
[
_Ty=X
,Iter=std::move\u迭代器
]
C:\Program Files(x86)\Microsoft Visual Studio 12.0\VC\include\vector(766):请参阅正在编译的函数模板实例化“void std::vector:::_Construct(_Iter,_Iter,std::forward_iterator_tag)”
具有
[
_Ty=X
,Iter=std::move\u迭代器
]
C:\ProgramFiles(x86)\Microsoft Visual Studio 12.0\VC\include\vector(854):请参阅正在编译的函数模板实例化“void std::vector::_Construct(_Iter,_Iter)”的参考
具有
[
_Ty=X
,Iter=std::move\u迭代器
]
C:\ProgramFiles(x86)\Microsoft Visual Studio 12.0\VC\include\vector(854):请参阅正在编译的函数模板实例化“void std::vector::_Construct(_Iter,_Iter)”的参考
具有
[
_Ty=X
,Iter=std::move\u迭代器
]
C:\ProgramFiles(x86)\Microsoft Visual Studio 12.0\VC\include\vector(849):编译类模板成员函数“void std::vector::_Assign_rv(std::vector&,std::false_type)”时
具有
[
_Ty=X
]
C:\Program Files(x86)\Microsoft Visual Studio 12.0\VC\include\vector(860):请参阅正在编译的函数模板实例化“void std::vector::_Assign_rv(std::vector&,std::false_type)”的参考
具有
[
_Ty=X
]
cpp(16):请参阅对正在编译的类模板实例化“std::vector”的引用
具有
[
_Ty=X
]
C++11的答案: VS符合原始规范,因为根据缺陷报告,
std::allocator的规范

导致对具有默认分配器的容器的移动分配运算符产生不必要的要求(
MoveInsertable
MoveAssignable

然而,这在C++14中是固定的。因此,现在
std::allocator
不再使此代码非法,根据N3797中的表96([20.2.1,container.requirements.general]),对
std::vector=:X的模板参数
T
的要求是

C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\xmemory0(600): error C2280: 'X::X(X &&)' : attempting to reference a deleted function
    Test.cpp(9) : see declaration of 'X::X'
    C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\xmemory0(723) : see reference to function template instantiation 'void std::allocator<_Ty>::construct<_Objty,_Ty>(_Objty *,_Ty &&)' being compiled
    with
    [
        _Ty=X
    ,   _Objty=X
    ]
    C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\xmemory0(723) : see reference to function template instantiation 'void std::allocator<_Ty>::construct<_Objty,_Ty>(_Objty *,_Ty &&)' being compiled
    with
    [
        _Ty=X
    ,   _Objty=X
    ]
    C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\xmemory0(872) : see reference to function template instantiation 'void std::allocator_traits<_Alloc>::construct<_Ty,_Ty>(std::allocator<_Ty> &,_Objty *,_Ty &&)' being compiled
    with
    [
        _Alloc=std::allocator<X>
    ,   _Ty=X
    ,   _Objty=X
    ]
    C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\xmemory0(872) : see reference to function template instantiation 'void std::allocator_traits<_Alloc>::construct<_Ty,_Ty>(std::allocator<_Ty> &,_Objty *,_Ty &&)' being compiled
    with
    [
        _Alloc=std::allocator<X>
    ,   _Ty=X
    ,   _Objty=X
    ]
    C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\xmemory(378) : see reference to function template instantiation 'void std::_Wrap_alloc<std::allocator<_Ty>>::construct<X,X>(_Ty *,X &&)' being compiled
    with
    [
        _Ty=X
    ]
    C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\xmemory(378) : see reference to function template instantiation 'void std::_Wrap_alloc<std::allocator<_Ty>>::construct<X,X>(_Ty *,X &&)' being compiled
    with
    [
        _Ty=X
    ]
    C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\xmemory(416) : see reference to function template instantiation '_FwdIt std::_Uninit_copy<_InIt,_FwdIt,std::allocator<_Ty>>(_InIt,_InIt,_FwdIt,std::_Wrap_alloc<std::allocator<_Ty>> &,std::_Nonscalar_ptr_iterator_tag)' being compiled
    with
    [
        _FwdIt=X *
    ,   _InIt=std::move_iterator<std::_Vector_iterator<std::_Vector_val<std::_Simple_types<X>>>>
    ,   _Ty=X
    ]
    C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\xmemory(427) : see reference to function template instantiation '_FwdIt std::_Uninit_copy<_Iter,X,_Alloc>(_InIt,_InIt,_FwdIt,_Alloc &)' being compiled
    with
    [
        _FwdIt=X *
    ,   _Iter=std::move_iterator<std::_Vector_iterator<std::_Vector_val<std::_Simple_types<X>>>>
    ,   _Alloc=std::_Wrap_alloc<std::allocator<X>>
    ,   _InIt=std::move_iterator<std::_Vector_iterator<std::_Vector_val<std::_Simple_types<X>>>>
    ]
    C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\vector(1640) : see reference to function template instantiation '_FwdIt std::_Uninitialized_copy<_Iter,X*,std::_Wrap_alloc<std::allocator<_Ty>>>(_InIt,_InIt,_FwdIt,_Alloc &)' being compiled
    with
    [
        _FwdIt=X *
    ,   _Iter=std::move_iterator<std::_Vector_iterator<std::_Vector_val<std::_Simple_types<X>>>>
    ,   _Ty=X
    ,   _InIt=std::move_iterator<std::_Vector_iterator<std::_Vector_val<std::_Simple_types<X>>>>
    ,   _Alloc=std::_Wrap_alloc<std::allocator<X>>
    ]
    C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\vector(789) : see reference to function template instantiation 'X *std::vector<X,std::allocator<_Ty>>::_Ucopy<_Iter>(_Iter,_Iter,X *)' being compiled
    with
    [
        _Ty=X
    ,   _Iter=std::move_iterator<std::_Vector_iterator<std::_Vector_val<std::_Simple_types<X>>>>
    ]
    C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\vector(789) : see reference to function template instantiation 'X *std::vector<X,std::allocator<_Ty>>::_Ucopy<_Iter>(_Iter,_Iter,X *)' being compiled
    with
    [
        _Ty=X
    ,   _Iter=std::move_iterator<std::_Vector_iterator<std::_Vector_val<std::_Simple_types<X>>>>
    ]
    C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\vector(766) : see reference to function template instantiation 'void std::vector<X,std::allocator<_Ty>>::_Construct<_Iter>(_Iter,_Iter,std::forward_iterator_tag)' being compiled
    with
    [
        _Ty=X
    ,   _Iter=std::move_iterator<std::_Vector_iterator<std::_Vector_val<std::_Simple_types<X>>>>
    ]
    C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\vector(766) : see reference to function template instantiation 'void std::vector<X,std::allocator<_Ty>>::_Construct<_Iter>(_Iter,_Iter,std::forward_iterator_tag)' being compiled
    with
    [
        _Ty=X
    ,   _Iter=std::move_iterator<std::_Vector_iterator<std::_Vector_val<std::_Simple_types<X>>>>
    ]
    C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\vector(854) : see reference to function template instantiation 'void std::vector<X,std::allocator<_Ty>>::_Construct<std::move_iterator<std::_Vector_iterator<std::_Vector_val<std::_Simple_types<X>>>>>(_Iter,_Iter)' being compiled
    with
    [
        _Ty=X
    ,   _Iter=std::move_iterator<std::_Vector_iterator<std::_Vector_val<std::_Simple_types<X>>>>
    ]
    C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\vector(854) : see reference to function template instantiation 'void std::vector<X,std::allocator<_Ty>>::_Construct<std::move_iterator<std::_Vector_iterator<std::_Vector_val<std::_Simple_types<X>>>>>(_Iter,_Iter)' being compiled
    with
    [
        _Ty=X
    ,   _Iter=std::move_iterator<std::_Vector_iterator<std::_Vector_val<std::_Simple_types<X>>>>
    ]
    C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\vector(849) : while compiling class template member function 'void std::vector<X,std::allocator<_Ty>>::_Assign_rv(std::vector<_Ty,std::allocator<_Ty>> &&,std::false_type)'
    with
    [
        _Ty=X
    ]
    C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\vector(860) : see reference to function template instantiation 'void std::vector<X,std::allocator<_Ty>>::_Assign_rv(std::vector<_Ty,std::allocator<_Ty>> &&,std::false_type)' being compiled
    with
    [
        _Ty=X
    ]
    Test.cpp(16) : see reference to class template instantiation 'std::vector<X,std::allocator<_Ty>>' being compiled
    with
    [
        _Ty=X
    ]
a = rv