首页 > 其他分享 >is_scoped_enum解析

is_scoped_enum解析

时间:2023-11-05 14:38:55浏览次数:43  
标签:std 作用域 enum value 枚举 scoped 解析 type

限定作用域枚举类型与不限定作用域枚举类型的区别在[1]的条款10中有较为详细的描述,其中一个要点为:

限定作用域枚举型仅在枚举类型内可见,他们只能通过强制类型转换以转换到其他的类型,换言之不支持隐式的类型转换,举个例子:

enum class Color : int32_t { // 限定作用域枚举
    black,
    white,
    red 
};

int32_t color = Color::black; // compile error :  cannot convert ‘Color’ to ‘int32_t’ {aka ‘int’} in initialization
enum Color : int32_t { // 非限定作用域枚举
    black,
    white,
    red 
};

int32_t color = Color::black; // compile ok

即限定作用的枚举类型不支持隐式类型转换,包括其自身的underlying_type;

std::is_enum

在C++11中提供了std::is_enum用于判断枚举类型:

#include <iostream>
#include <type_traits>
 
class A {};
 
enum E {};
 
enum class Ec : int {};
 
int main() 
{
    std::cout << std::boolalpha;
    std::cout << std::is_enum<A>::value << '\n';    // false
    std::cout << std::is_enum<E>::value << '\n';    // true
    std::cout << std::is_enum<Ec>::value << '\n';   // true
    std::cout << std::is_enum<int>::value << '\n';  // false
}

那么如何判断E和Ec?在C++23中会提供 std::is_scoped_enum

is_scoped_enum

在前文中说明限定作用域枚举类型不支持隐式转换为其underlying_type,因此可以利用这一点实现:

template <typename T, typename = std::void_t<>>
struct is_scoped_enum : std::false_type {};

template <typename T> 
struct is_scoped_enum<T, std::void_t<std::enable_if_t<!std::is_convertible_v<T, std::underlying_type_t<T>> && std::is_enum_v<T>>>> : std::true_type {};
std::cout << is_scoped_enum<A>::value << '\n';    // false
    std::cout << is_scoped_enum<E>::value << '\n';    // false
    std::cout << is_scoped_enum<Ec>::value << '\n';   // true
    std::cout << is_scoped_enum<int>::value << '\n';  // false

这里还可以修改为:

template <typename T, typename V = void>
struct Unscope : std::false_type {};

template <typename T>
struct Unscope<T, decltype(+T{})> : std::true_type {};

template <typename T>
using is_scoped_enum = std::integral_constant<bool, !Unscope<T>::value && std::is_enum<T>::value>;

这里引入一个知识点:

is_scoped_enum解析_cpp

If the operand passed to a built-in arithmetic operator is integral or unscoped enumeration type, then before any other action (but after lvalue-to-rvalue conversion, if applicable), the operand undergoes integral promotion. [2]

一元+运算符会对整型(无限行作用域枚举类型)进行隐式integral promotion,即小整数类型(如 char)和无作用域枚举类型的纯右值可转换成较大整数类型(如 int)的纯右值。具体而言,算术运算符不接受小于 int 的类型作为它的实参,而在左值到右值转换后,如果适用就会自动实施整数提升。

备注: If an operand has array or function type, array-to-pointer and function-to-pointer conversions are applied. 例如lambda 表达式转成函数指针

因此限定作用域枚举类型不满足+T{}表达式,通过SFINE得到Unscope<T>::value的值为false;

若此时对一元+重载:

enum class Ec : int {
};

Ec operator+(const Ec &ec)
{
    return Ec{};
}

让Ec支持一元加的隐式integral promotion,则判断错误:

std::cout << is_scoped_enum<Ec>::value << '\n';   // false

参考资料

【1】Effective Modern C++

【2】https://en.cppreference.com/w/cpp/language/operator_arithmetic

标签:std,作用域,enum,value,枚举,scoped,解析,type
From: https://blog.51cto.com/u_13137973/8191903

相关文章

  • 封装JWT - 生成 jwt 和解析 jwt
    1.ASP.NETCore身份验证和授权验证的功能由Authentication,Authorization中间件提供:app.UseAuthentication(),app.UseAuthorization()。2.控制器类上标注[Authorzie]的控制器则所有的操作方法都会被进行身份验证和授权验证,对于对标注了[Authorize]的控制器类,如果某个方法不想......
  • 深度解析BERT:从理论到Pytorch实战
    本文从BERT的基本概念和架构开始,详细讲解了其预训练和微调机制,并通过Python和PyTorch代码示例展示了如何在实际应用中使用这一模型。我们探讨了BERT的核心特点,包括其强大的注意力机制和与其他Transformer架构的差异。关注TechLead,分享AI全维度知识。作者拥有10+年互联网服务架......
  • 二十六、QT发送http请求并解析返回的json数据
    1.使用的模块和类模块:network类:QNetworkAccessManager、QNetworkRequest、QNetworkReply、QJsonDocument、QJsonObject、QJsonArrayQSslSocket::sslLibraryBuildVersionString();:查看当前使用的ssl版本,访问HTTPS时需要使用、复制libcrypto-1_1-x64.dll和libssl-1_1......
  • 探针探测对sts pod域名解析是否成功的影响
    初始情况apiVersion:v1kind:Servicemetadata:name:nginxspec:ports:-port:80selector:app:nginx---apiVersion:apps/v1kind:StatefulSetmetadata:name:nginxspec:podManagementPolicy:ParallelserviceName:nginxreplicas:2s......
  • 全网最详细4W字Flink全面解析与实践(下)
    本文已收录至GitHub,推荐阅读......
  • C++参数解析参数
    《C/C++参数解析》1.getopt库的使用  getopt用于解析程序命令行输入的参数,可解析短参数和长参数;解析短参数使用getopt()函数,解析长参数可使用getopt_long();1.1getopt()解析短参数  getopt()函数用来解析短参数,例如-a或者-b100这样的参数,不能解析长参数,如--ip198.11.2......
  • 全网最详细4W字Flink全面解析与实践(上)
    本文已收录至GitHub,推荐阅读......
  • JavaScript 函数、函数构造、函数调用、参数、函数返回值、变量的作用域、预解析
    一、函数及函数的构造函数是一个可重用的代码块,用来完成某个特定功能。每当需要反复执行一段代码时,可以利用函数来避免重复书写相同代码。函数包含着的代码只能在函数被调用时才会执行,就可以避免页面载入时执行该脚本简单来说就是一个封装,封装的是一个特定的功能,重复使用函......
  • 数据库问题解析
    1、表连接表连接(JOIN)是在多个表中间通过⼀定的连接条件,使表之间发⽣关联进⽽能从多个表之间获取数据。2、3、表联合union:对两个结果集进⾏并集操作,不包括重复⾏unionall:对两个结果集进⾏并集操作,包括重复⾏注意事项:①每条SELECT语句必须拥有相同数量的列;②每条SELE......
  • 一个Python爬虫案例,带你掌握xpath数据解析方法!
    xpath基本概念xpath解析:最常用且最便捷高效的一种解析方式。通用性强。xpath解析原理1.实例化一个etree的对象,且需要将被解析的页面源码数据加载到该对象中2.调用etree对象中的xpath方法结合xpath表达式实现标签的定位和内容的捕获。环境安装pipinstalllxml如何实例化一个etree对......