If you have a std::variant
with duplicate types, how do you assign to it? std::variant
seemingly allows duplicate types.
std::variant<int,int> foo;
compiles successfully, and yet I am unsure how to assign to foo
, doubly so if I wish to assign to a particular entry in the variant.
I have tried:
std::variant<int,int> foo;
foo = 1;
fails to compile, with the error that =
is undefined for std::variant<int,int>
.
std::variant<int,int> foo;
get<foo, 0> = 1;
fails to compile with the error that there is insufficient contextual type information to determine type.
I want something like
std::variant<int,int> foo;
something<foo, 1> = 10
assert(foo.index == 1);
assert(get<1>(foo) == 10);
This will place the variant into a state where the 0th alternative is active and its value is 1:
foo.emplace<0>(1);
Note that the semantics of emplace
are not, in general, identical to those of assignment. The assignment operator first checks whether the currently active alternative is the same one that is supposed to be active after the assignment. If so, it simply assigns to the existing alternative. In contrast, emplace
always destroys the currently active alternative first and then constructs one, even if the new alternative has the same index as the old one. To use assignment semantics, you would do something like this:
if (auto* p = std::get_if<0>(&foo)) {
*p = 1;
} else {
foo.emplace<0>(1);
}
For ints, it makes no difference, but for more complex types, assignment can sometimes be more efficient than destroying the object and creating a new one with the desired value.