Let's say that I have this object:
struct foo {
std::unique_ptr<int> mem;
virtual ~foo() = default;
};
I can no longer return a foo
object created in a function:
foo make_foo() {
foo result;
result.mem = std::make_unique<int>({});
return result;
}
As may be indicated I need the destructor to be virtual because this will be a base class. But even if I'm using the default destructor, that's not enough, I still can't return an object created in a function.
I get the error:
error C2280: foo::foo(const foo &): attempting to reference a deleted function
Is there a way to navigate around this issue?
Per [class.copy.ctor]/8
If the definition of a class X does not explicitly declare a move constructor, a non-explicit one will be implicitly declared as defaulted if and only if [...]
- X does not have a user-declared destructor.
Since
virtual ~foo() = default;
is a user-declared destructor you no longer have a move constructor so it tries to use the copy constructor but can't because that is deleted as you have a non-copyable member.
To get the move constructor back, and to keep the default constructable, you need to add
foo() = default;
foo(foo&&) = default;
foo &operator=(foo &&) = default; // add this if you want to move assign as well
to foo
The reason you have to add foo() = default;
when you add foo(foo&&) = default;
is that foo(foo&&) = default;
is a used-declared constructor and if you have any user-declared constructors then the default constructor is no longer provided.
This is a "hack" but what you could do is move the virtual destructor into another class and then inherit from that. That will give you a virtual destructor in foo
without having to declare it and give you the default constructors you want. That would look like
struct make_virtual
{
virtual ~make_virtual() = default;
};
struct foo : make_virtual {
std::unique_ptr<int> mem;
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With