The following sample builds and runs properly with the line Container container2(container1);
removed. It appears the copy constructor for std::variant
itself is deleted, which makes my Container
's copy constructor implicitly deleted.
Effectively, I'm asking:
std::variant
as a member?Container
before safe copy/move assignment is allowed?#include <string>
#include <variant>
class A {};
class Container {
public:
Container(int i) : data_(i) {}
Container(float f) : data_(f) {}
Container(std::string s) : data_(s) {}
Container(std::unique_ptr<A> a) : data_(std::move(a)) {}
std::variant<int, float, std::string, std::unique_ptr<A>> data_;
};
int main() {
Container container1{3};
// error: call to implicitly-deleted copy constructor of 'Container'
//
// copy constructor of 'Container' is implicitly deleted because
// field 'data_' has a deleted copy constructor
Container container2(container1);
return 0;
}
cppreference has this to say about std::variant
's copy constructor:
Copy constructor. [...] This constructor is defined as deleted unless
std::is_copy_constructible_v<T_i>
is true for allT_i
inTypes
. [...]
In other words, it is not deleted unless one or more of the types that the std::variant
can contain is not copyable for whatever reason. In your case, it's the std::unique_ptr
that's causing the problem. Perhaps std::shared_ptr
would be more appropriate.
Extending Paul Sanders' answer: what kind of copy do you want?
If it is a shallow copy, use shared_ptr<A>
.
If it is a deep copy, why not have variant<..,A>
? If the reason is that A
is polymorphic, then the real problem is cloning each of the derived classes. You have to create your own mechanism for the cloning and your own copyable smart pointer to use it - as far as I know, there is nothing in the standard library to help you.
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