我正在努力解决这段代码的奇怪行为。问题是这个片段的输出是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";
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 函数的两个版本都已实例化,但只调用了一个。
在此声明中
auto var = std::holds_alternative<int>(lhs) ? std::get<int>(lhs) : std::get<double>(lhs);
使用了条件运算符。编译器根据运算符的操作数确定结果的类型。由于通常的算术转换,常见类型是 double。