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:
- What is the proper way to store a
std::variant
as a member? - What must be implemented in
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: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 thestd::unique_ptr
that's causing the problem. Perhapsstd::shared_ptr
would be more appropriate.