std::variant 的奇怪结果

问题描述 投票:0回答:2

我正在努力解决这段代码的奇怪行为。问题是这个片段的输出是double。但我们在 lhs 中有 int 。我挖掘了一段时间,发现编译器出于某种原因将垃圾双精度值放入 var 中。然后这将变量的类型变成了 double。这会破坏我在外部作用域的所有代码,因为我根据变量的类型执行一些操作。我缺少什么?这应该是这样的吗?

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";
c++ c++17 clang variant std-variant
2个回答
0
投票
std::variant<int, double> lhs = 4;

so

lhs
是一个包含
int
double
的变体。 当您在其中存储
int
时,它会保存一个
int

auto var = std::holds_alternative<int>(lhs) ? std::get<int>(lhs) : std::get<double>(lhs);

这与

相同
auto var = true ? std::get<int>(lhs) : std::get<double>(lhs);

这是

auto var = true ? (int)4 : double(3.14);

var
的类型计算为
double
,但其值是
4

double var = 4;

auto
不是运行时动态类型;它是编译时计算类型。

if (std::strcmp(typeid(var).name(), "i") == 0)
  std::cout << "int";
else
  std::cout << "double";

打印

"double"

我想你想做的是这样的:

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

按预期打印

"int"

在这里,我们创建一个访问者函数。

std::visit
进行运行时切换来决定
lhs
包含哪种类型,并调用与
lhs
中的类型匹配的类型。

要小心,因为 lambda 函数的两个版本都已实例化,但只调用了一个。


0
投票

在此声明中

auto var = std::holds_alternative<int>(lhs) ? std::get<int>(lhs) : std::get<double>(lhs);

使用了条件运算符。编译器根据运算符的操作数确定结果的类型。由于通常的算术转换,常见类型是 double。

© www.soinside.com 2019 - 2024. All rights reserved.