I'm struggling with an odd behavior of the below code. The problem is that output of this snippet is "double"
. But we have an int
in lhs
.
I dug for a while and figured out the compiler put a garbage double
value into var
for some reason. Then this turned the type of the variable into double
. This breaks all my code at the outer scope, because I do some operations according to the type of the variable.
What am I missing? Is it supposed to work like this?
std::variant<int, double> lhs = 4;
auto var = std::holds_alternative<int>(lhs) ? std::get<int>(lhs) : std::get<double>(lhs);
if (std::strcmp(typeid(var).name(), "i") == 0)
std::cout << "int";
else
std::cout << "double";
std::variant<int, double> lhs = 4;
so lhs
is a variant holding either an int
or a double
. As you stored an int
in it, it holds an int
.
auto var = std::holds_alternative<int>(lhs) ? std::get<int>(lhs) : std::get<double>(lhs);
this is the same as
auto var = true ? std::get<int>(lhs) : std::get<double>(lhs);
which is
auto var = true ? (int)4 : double(3.14);
The type of var
is computed to be double
, but its value is 4
.
double var = 4;
auto
is not a runtime dynamic type; it is a compile time computed type.
if (std::strcmp(typeid(var).name(), "i") == 0)
std::cout << "int";
else
std::cout << "double";
which prints "double"
.
I think what you want to do is this:
std::variant<int, double> lhs = 4;
std::visit( [&](auto var){
if (std::strcmp(typeid(var).name(), "i") == 0)
std::cout << "int";
else
std::cout << "double";
}, lhs);
which prints "int"
as expected.
Here, we create a visitor function. std::visit
makes a runtime switch to decide which type lhs
contains, and calls the one that matches the type within lhs
.
Be careful, because both versions of the lambda function are instantiated, but only one is called.