C++ Compiler Error C2280 “attempting to reference a deleted function” in Visual Studio 2013 and 2015

后端 未结 7 964
误落风尘
误落风尘 2020-11-27 18:03

This snippet is compiled without errors in Visual Studio 2013 (Version 12.0.31101.00 Update 4)

class A
{
public:
   A(){}
   A(A &&){}
};

int main(i         


        
相关标签:
7条回答
  • 2020-11-27 18:47

    I ran into a similar situation where I had a hierarchy of classes and a destructor in the base class was declared virtual. In this case, compiler does NOT automatically generate move and copy constructors. So we have to default these in order for compiler to generate the definitions for these methods.

    However, I ran into another issue after I defaulted copy and move constructor. I saw that the compiler was still not able to generate copy and move constructors. The reason was the usage of std::atomic member variable in the base class. Since atomic variable are not copy able or movable, the compiler could not generate definitions for copy constructor. This gave me lot of headache and I had to solve the problem using a different method. See other great answers for similar issue that I faced.

    References: Does a default virtual destructor prevent compiler-generated move operations?

    Error with copy constructor/assignment operator for a class which has std::atomic member variable

    0 讨论(0)
  • 2020-11-27 18:52

    I had the same problem and it was due to a poorly defined member variable:

    double const deltaBase = .001;
    

    Putting this in will cause the copy constructor to be deleted. Get rid of the "const" and assign in the constructor.

    0 讨论(0)
  • 2020-11-27 18:57

    I was stuck with this error even after "default"ing the copy ctor. Turned out, one of my class member (rapidjson's Document object) was disallowing copy. Changed it to a reference, initialized via a *(new rapidjson::Document()) in the default ctor's initializer list. Looks like all individual members should also be copy'able in addition to the defaulted copy ctor.

    0 讨论(0)
  • 2020-11-27 18:57

    I encountered the same error, just because I had misused std::unique_ptr.

    Note that std::unique_ptr is non-copyable, it is only moveable.

    Here is the wrong demonstration.

    class word;
    class sentence
    {
        public:
            sentence();
            ~sentence();
    
        public:
            // Wrong demonstration, because I pass the parameter by value/copying
            // I should use 'std::shared_ptr< word >' instead.
            sentence(std::initializer_list< std::unique_ptr< word > > sentence);
    };
    

    The following code is taken from MSVC compiler's STL library. We can see that the copy constructor and copy assignment operator of class unique_ptr are deleted explicitly.

        unique_ptr(const unique_ptr&) = delete;
        unique_ptr& operator=(const unique_ptr&) = delete;
    
    0 讨论(0)
  • 2020-11-27 19:00

    From [class.copy]/7, emphasis mine:

    If the class definition does not explicitly declare a copy constructor, a non-explicit one is declared implicitly. If the class definition declares a move constructor or move assignment operator, the implicitly declared copy constructor is defined as deleted; otherwise, it is defined as defaulted (8.4). The latter case is deprecated if the class has a user-declared copy assignment operator or a user-declared destructor.

    There is an equivalent section with similar wording for copy assignment in paragraph 18. So your class is really:

    class A
    {
    public:
       // explicit
       A(){}
       A(A &&){}
    
       // implicit
       A(const A&) = delete;
       A& operator=(const A&) = delete;
    };
    

    which is why you can't copy-construct it. If you provide a move constructor/assignment, and you still want the class to be copyable, you will have to explicitly provide those special member functions:

        A(const A&) = default;
        A& operator=(const A&) = default;
    

    You will also need to declare a move assignment operator. If you really have a need for these special functions, you will also probably need the destructor. See Rule of Five.

    0 讨论(0)
  • 2020-11-27 19:07

    If you write a user-defined move constructor for your class, the copy constructor will be deleted. This is because if a class needs special behaviour for its move constructor, it probably needs some similar behaviour in its copy constructor, so the copy constructor will be deleted to stop you from inadvertently using the default behaviour.

    If you want to define your own move constructor and use the default copy constructor, you need to declare it as default, like you suggested in your question:

    class A
    {
    public:
       A(){}
       A(A &&){}
       //I know what I'm doing, compiler, use the default version.
       A(const A&)=default;
    };
    

    Note that if you define a custom move constructor, you should think about your assignment operators and destructor as well.

    0 讨论(0)
提交回复
热议问题