Reputation: 148
According to cppreference, variant is not allowed to allocate dynamic memory. This suggests that variant should not have dynamically-allocated containers as template, like vectors and maps. Yet, some say that it is possible to have a vector as a variant template. Could it be that the variant stores the vector pointer or reference, rather than the actual structure itself?
I would like to have a variant storing a vector and a map. I thought of 2 possibilities:
std::variant<std::vector<int>, std::map<int, int> > x; //stores within the variant itself ??
std::variant <std::uniqur_ptr<std::vector<int> >, std::unique_ptr<std::map<int, int> > > y; //stores only a pointer. The container is allocated elsewhere.
I would prefer the first option for its simplicity. Let me know what you think!
Upvotes: 6
Views: 2063
Reputation: 62704
According to cppreference, variant is not allowed to allocate dynamic memory.
You are misunderstanding what that means. std::variant
is not allowed to be implemented by dynamically allocating the contained object, but that contained object is allowed to do whatever it normally does.
It is the difference between
class incorrect_variant {
union {
std::vector<int> * vector;
std::map<int, int> * map;
} u;
enum kind {
is_vec,
is_map,
} k;
public:
incorrect_variant(std::vector<int> value) : u(new std::vector<int>(value)), k(is_vec) {}
// etc
}
class correct_variant {
std::aligned_storage<std::max(sizeof(std::vector<int>), sizeof(std::map<int, int>)> storage;
enum kind {
is_vec,
is_map,
} k;
public:
correct_variant(std::vector<int> value) : k(is_vec)
{
new (storage) std::vector<int>(value);
}
// etc
}
Upvotes: 3
Reputation: 29975
You're getting it wrong.
The variant
class itself allocates not a single byte (otherwise it would probably have an allocator template argument). Everything is locally in the class. But the "varianted" types themselves can allocate as much memory as they like. They own their own memory and none of this concerns std::variant
. Isn't a bit like an array of std::string
s. Sure, a C array doesn't allocate anything on its own, but the individual elements (strings) must do some allocation.
Upvotes: 0
Reputation: 15814
std::vector<T>
is a class with a pointer that manages dynamically allocated memory.
std::variant
by not "being allowed to allocate memory" wouldn't be able to store the std::vector<T>
object itself in dynamic memory, but the vector can manage its own dynamic memory just as fine.
Upvotes: 0