程序问答   发布时间:2022-06-01  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了为什么将 int 分配给 std::variant<long int, ...> 失败?大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

如何解决为什么将 int 分配给 std::variant<long int, ...> 失败??

开发过程中遇到为什么将 int 分配给 std::variant<long int, ...> 失败?的问题如何解决?下面主要结合日常开发的经验,给出你关于为什么将 int 分配给 std::variant<long int, ...> 失败?的解决方法建议,希望对你解决为什么将 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 需要“整型转换”来匹配 1long int。因此,将 1 分配给 bool 是一个编译时错误。如果备选方案是 vint,那么 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@
@H_772_105@

大佬总结

以上是大佬教程为你收集整理的为什么将 int 分配给 std::variant<long int, ...> 失败?全部内容,希望文章能够帮你解决为什么将 int 分配给 std::variant<long int, ...> 失败?所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。