c++ - 为什么将 int 分配给 std::variant失败?
问题描述
在分配给变体时,我觉得我缺少一些关于 int 类型提升的明显内容。
在 gcc 版本 9.3.0(Ubuntu 9.3.0-11ubuntu0~18.04.1)上,使用 -std=c++17 编译,以下代码编译失败:
#include <variant>
#include <iostream>
int main()
{
std::variant<long int, bool> v; // works fine if "long" is omitted
long int sanity = 1; // verify that we can assign 1 to a long int; works fine
std::cout << sizeof(sanity) << "\n";
v = 1; // compiler error here: why doesn't this assign to the long int variant of v?
return 0;
}
错误信息:
error: no match for ‘operator=’ (operand types are ‘std::variant<long int, bool>’ and ‘int’)
是否有任何魔法可以让这项工作按预期进行,而不需要在作业中进行显式转换?谢谢!
解决方案
分配给变体并不是简单地分配给变体中当前活动的类型。相反,右手边的类型用于确定哪些可能的类型(替代品)是右手边的最佳匹配。然后,该类型被分配给。
因此,v = 1;
不会自动分配给long int
已经在里面的值v
,而是进行编译时计算以确定是否long int
更好bool
地匹配int
(右侧的类型)。最佳匹配是使用重载解决规则确定的。换句话说,我们必须想象存在两个函数
void f(long int);
void f(bool);
并问自己将调用哪个函数f(1)
。如果long int
选择了重载,则v = 1
分配给long int
对象。如果bool
选择了重载,long int
则当前在其中v
的 将被销毁,并bool
使用值 1 构造一个新对象。
不幸的是,这种重载解决方案是模棱两可的:1
需要“积分转换”来匹配long int
or bool
。因此,分配 1v
是编译时错误。如果备选方案是int
和bool
,那么int
备选方案将产生完全匹配并且不会有歧义。
这个特定的例子在 C++20 中是固定的:替代方案被排除在考虑之外,因为从一个值初始化一个值bool
需要缩小转换。因此,在 C++20 中,此代码将始终分配给替代项(如果当前在变体中存在对象,则将其销毁)。bool
int
long int
bool
推荐阅读
- android - 如何确保在应用程序崩溃时存储日志并允许在颤动中发送给开发人员?
- javascript - 带有事件处理程序的 for 循环
- c# - 将 Label 和 PickerView 放在 TableView 的同一行
- c++ - 有没有优雅的方法在多态 lambda 中编写类型别名
- java - 如何调试 CompletableStage 死锁?
- java - 在java中创建一个交替数组方法,你能告诉我哪里出错了吗?
- python - Python中三角函数的求和
- batch-file - 在批处理脚本中向我的文件名添加零
- jquery - 如何在输入时在 Bootstrap (4) 模态提交中制作只有隐藏输入的表单?
- python - unicode dict 键的令人惊讶的行为