大佬教程收集整理的这篇文章主要介绍了为什么将 int 分配给 std::variant<long int, ...> 失败?,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
在分配给变体时,我觉得我遗漏了一些关于 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
值,而是进行编译时计算以确定 {{1 }} 或 long int
更适合 bool
(右侧的类型)。最佳匹配是使用重载解析规则确定的。换句话说,我们必须想象存在两个函数
int
然后问问自己 void f(long int);
void f(bool);
会调用哪个函数。如果选择了 f(1)
重载,则 long int
分配给 v = 1
对象。如果选择了 long int
重载,则当前位于 bool
中的 long int
将被销毁,并使用值 1 构造一个新的 v
对象。
不幸的是,这个重载决议是模棱两可的:bool
需要“整型转换”来匹配 1
或 long int
。因此,将 1 分配给 bool
是一个编译时错误。如果备选方案是 v
和 int
,那么 bool
备选方案将产生完全匹配并且不会有歧义。
此特定示例在 C++20 中得到修复:int
替代方案已被排除在考虑范围之外,因为从 bool
值初始化 bool
值需要进行缩小转换。因此,在 C++20 中,此代码将始终分配给 int
替代项(如果当前在变体中存在 long int
对象,则该对象将被销毁)。
从 int 转换为这两种类型具有相同的“距离”。
它不知道您要分配给哪个。
您可以创建一个拒绝从 int 转换的非 bool 布尔值。
struct Boolean{
bool value=false;
constexpr Boolean()=default;
template<class T,std::enable_if_t<std::is_integral<T>{},bool> =true>
Boolean(T)=delete;
constexpr Boolean(bool b):value(b){}
constexpr Boolean(Boolean const&)=default;
constexpr Boolean& operator=(Boolean const&)=default;
constexpr explicit operator bool()const{return value;}
constexpr friend bool operator==(Boolean lhs,Boolean rhs) { return lhs.value==rhs.value; }
constexpr friend bool operator!=(Boolean lhs,Boolean rhs) { return lhs.value!=rhs.value; }
};
也许还有一些操作。
那么 variant<Boolean,long int>
不会从 int
转换。
Live example。
@H_772_105@以上是大佬教程为你收集整理的为什么将 int 分配给 std::variant<long int, ...> 失败?全部内容,希望文章能够帮你解决为什么将 int 分配给 std::variant<long int, ...> 失败?所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。