(declared implicitly) cannot be referenced -- it is a deleted function
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;
}
CodeDevil
Updated on June 16, 2022Comments
-
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 theXYZ
class, so it can be used in other functions of theXYZ
class.How can I resolve this error?