(declared implicitly) cannot be referenced -- it is a deleted function

10,829

This is the declaration of class ABC:

namespace abcd
{
    class ABC
    {
    public:
        ABC() = delete;
        ABC(const std::string& filename);
        virtual ~ABC();
        ABC(const ABC&) = delete;
        ABC(ABC&&) = default;
    };
}

Referring to MSVC error C2280:

The compiler detected an attempt to reference a deleted function. This error can be caused by a call to a member function that has been explicitly marked as = deleted in the source code. This error can also be caused by a call to an implicit special member function of a struct or class that is automatically declared and marked as deleted by the compiler. For more information about when the compiler automatically generates default or deleted special member functions, see Special member functions.

In your case, apart from the conversion constructor, your class ABC only has a move constructor. The compiler has implicitly declared the copy assignment operator and move assignment operator as deleted. That's why you're getting this error. This line is trying to invoke your deleted copy assignment operator:

obj = maskfilename("abcd.txt"); //Error

Since you want your class to be a move-only class, just declare a move assignment operator and then the same line will invoke your move assignment operator. Then the rvalue that maskfilename returns will be moved into obj.

Here's a reworked implementation of your class ABC:

class ABC
{
public:
    ABC() = delete;
    ABC(std::string filename) : mFilename(std::move(filename)) {}
    virtual ~ABC() = default;
    ABC(const ABC&) = delete;
    ABC& operator= (const ABC&) = delete;
    ABC(ABC&&) = default;
    ABC& operator= (ABC&&) = default;
    std::string GetFilename() const { return mFilename; }

private:
    std::string mFilename;
};

In your class XYZ you can't have a member variable obj of type ABC since the default constructor is deleted. If you need to use such an object in other methods of XYZ you could have a unique pointer to ABC instead. So I would change that like this:

XYZ.h:

#include "ABC.h"
#include <memory>

class XYZ
{
public:
    void func();

private:
    std::unique_ptr<ABC> obj;
    std::unique_ptr<ABC> maskfilename(std::string filename);
};

XYZ.cpp:

void XYZ::func()
{
    obj = std::move(maskfilename("abcd.txt"));
}

std::unique_ptr<ABC> XYZ::maskfilename(std::string filename)
{
    std::unique_ptr<ABC> ret = std::make_unique<ABC>(filename);
    // blah blah...
    return ret;
}
Share:
10,829
CodeDevil
Author by

CodeDevil

Updated on June 16, 2022

Comments

  • CodeDevil
    CodeDevil almost 2 years

    With the following code, I'm facing an issue.

    ABC.h

    namespace abcd
    {
        class ABC
        {
        public:
            ABC() = delete;
            ABC(const std::string& filename);
            virtual ~ABC();
            ABC(const ABC&) = delete;
            ABC(ABC&&) = default;
        };
    }
    

    XYZ.h

    using namespace abcd;
    
    class XYZ
    {
    public:
        void func();
    private:
        ABC obj;
        ABC maskfilename(std::string filename);
    };
    

    XYZ.cpp

    XYZ::func()
    {
        obj = maskfilename("abcd.txt"); //Error
    }
    
    abcd::ABC XYZ::maskfilename(string filename)
    {
        abcd::ABC ret;
        // blah blah...
        return ret;
    }
    

    Error:

    "abcd::ABC::operator=(const abcd::ABC &)" (declared implicitly) cannot be referenced -- it is a deleted function

    I understand it is move constructor only class (ABC).

    What is the right way to use this? I want to retain the return value from maskfilename() in the XYZ class, so it can be used in other functions of the XYZ class.

    How can I resolve this error?