Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Weird result of std::variant

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?

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

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";

>Solution :

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.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading