C++错误:在移动构造函数中使用已删除的函数

Sou*_*rav 3 c++ constructor move-semantics

#include<iostream>
#include<vector>

class Container {
    int * m_Data;
public:
    Container() {
        //Allocate an array of 20 int on heap
        m_Data = new int[20];

        std::cout << "Constructor: Allocation 20 int" << std::endl;
    }

    ~Container() {
        if (m_Data) {
            delete[] m_Data;
            m_Data = NULL;
        }
        std::cout << "Destructor called" << std::endl;
    }

    Container(const Container & obj) {
        //Allocate an array of 20 int on heap
        m_Data = new int[20];

        //Copy the data from passed object
        for (int i = 0; i < 20; i++)
            m_Data[i] = obj.m_Data[i];

        std::cout << "Copy Constructor: Allocation 20 int" << std::endl;
    }

    // will give error on adding
    Container(Container&&) = delete;

};

// Create am object of Container and return
Container getContainer() 
{
    Container obj;
    return obj;
}

int main() {
    // Create a vector of Container Type
    std::vector<Container> vecOfContainers;

    //Add object returned by function into the vector
    vecOfContainers.push_back(getContainer());

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我已经编写了上面的代码作为实践来验证当从getContainer()返回对象时调用复制构造函数,即使它是一个右值.

我知道,如果用户定义的拷贝构造函数存在,那么编译器不会宣布此举的构造函数作为其与签名类的非显式内联公共成员T ::牛逼(T &&).我仍然决定添加"Container(Container &&)= delete;"行 并在编译期间得到以下错误::

moveconstructorIntro.cpp: In function ‘Container getContainer()’:
moveconstructorIntro.cpp:44:12: error: use of deleted function 
‘Container::Container(Container&&)’
     return obj;
            ^
moveconstructorIntro.cpp:36:5: error: declared here
     Container(Container&&) = delete;
     ^
In file included from /usr/include/c++/4.8.2/x86_64-redhat-
linux/bits/c++allocator.h:33:0,
                 from /usr/include/c++/4.8.2/bits/allocator.h:46,
                 from /usr/include/c++/4.8.2/string:41,
                 from /usr/include/c++/4.8.2/bits/locale_classes.h:40,
                 from /usr/include/c++/4.8.2/bits/ios_base.h:41,
                 from /usr/include/c++/4.8.2/ios:42,
                 from /usr/include/c++/4.8.2/ostream:38,
                 from /usr/include/c++/4.8.2/iostream:39,
                 from moveconstructorIntro.cpp:5:
/usr/include/c++/4.8.2/ext/new_allocator.h: In instantiation of ‘void __gnu_cxx::new_allocator<_Tp>::construct(_Up*, _Args&& ...) [with _Up = Container; _Args = {Container}; _Tp = Container]’:
/usr/include/c++/4.8.2/bits/alloc_traits.h:254:4:   required from ‘static typename std::enable_if<std::allocator_traits<_Alloc>::__construct_helper<_Tp, _Args>::value, void>::type std::allocator_traits<_Alloc>::_S_construct(_Alloc&, _Tp*, _Args&& ...) [with _Tp = Container; _Args = {Container}; _Alloc = std::allocator<Container>; typename std::enable_if<std::allocator_traits<_Alloc>::__construct_helper<_Tp, _Args>::value, void>::type = void]’
/usr/include/c++/4.8.2/bits/alloc_traits.h:393:57:   required from ‘static decltype (_S_construct(__a, __p, (forward<_Args>(std::allocator_traits::construct::__args)...)) std::allocator_traits<_Alloc>::construct(_Alloc&, _Tp*, _Args&& ...) [with _Tp = Container; _Args = {Container}; _Alloc = std::allocator<Container>; decltype (_S_construct(__a, __p, (forward<_Args>(std::allocator_traits::construct::__args)...)) = <type error>]’
/usr/include/c++/4.8.2/bits/vector.tcc:97:40:   required from ‘void std::vector<_Tp, _Alloc>::emplace_back(_Args&& ...) [with _Args = {Container}; _Tp = Container; _Alloc = std::allocator<Container>]’
/usr/include/c++/4.8.2/bits/stl_vector.h:920:36:   required from ‘void std::vector<_Tp, _Alloc>::push_back(std::vector<_Tp, _Alloc>::value_type&&) [with _Tp = Container; _Alloc = std::allocator<Container>; std::vector<_Tp, _Alloc>::value_type = Container]’
moveconstructorIntro.cpp:52:45:   required from here
/usr/include/c++/4.8.2/ext/new_allocator.h:120:4: error: use of deleted 
function ‘Container::Container(Container&&)’
  { ::new((void *)__p) _Up(std::forward<_Args>(__args)...); }
    ^
moveconstructorIntro.cpp:36:5: error: declared here
     Container(Container&&) = delete;
     ^
Run Code Online (Sandbox Code Playgroud)

出错的原因是什么?

请不要试图找到我在这里做的任何用例.我刚开始用C++编写代码并试图掌握.

Ser*_*eyA 5

当您明确删除移动构造函数时,您可以将其用于重载解析.

当按值返回本地参数时,移动构造函数被选为更好的重载候选者(在复制构造函数上),但由于它被删除而无法使用.

请记住,不是声明移动构造函数并明确删除它会产生与重载解析过程不同的结果!

编辑

虽然我上面说的是真实的,但是在这个代码中编译器报告的特定报告是在另一个区域,即当值被推回容器时发生移动尝试.同样的事情发生在那里 - 在重载解析期间选择了移动构造函数,但是在删除时不能使用它.