加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – SFINAE没有发生std ::底层类型

发布时间:2020-12-16 03:27:04 所属栏目:百科 来源:网络整理
导读:下面的SFINAE代码与可变模板很好地使用clang 3.7.1,C 14: #include array#include iostream#include vector#include cstdintenum class Bar : uint8_t { ay,bee,see};struct S {static void foo() {}// std::begin(h) is defined for h of type Htemplatety
下面的SFINAE代码与可变模板很好地使用clang 3.7.1,C 14:
#include <array>
#include <iostream>
#include <vector>
#include <cstdint>

enum class Bar : uint8_t {
    ay,bee,see
};

struct S {

static void foo() {}

// std::begin(h) is defined for h of type H
template<typename H,typename... T>
static typename std::enable_if<std::is_pointer<decltype(std::begin(std::declval<H>()))*>::value>::type 
foo(const H&,T&&... t) 
{ std::cout << "containern"; foo(std::forward<T>(t)...); }

// H is integral
template<typename H,typename... T>
static typename std::enable_if<std::is_integral<typename std::remove_reference<H>::type>::value>::type 
foo(const H&,T&&... t) 
{ std::cout << "integern"; foo(std::forward<T>(t)...); }

// H is an enum with underlying type = uint8_t
/*
template<typename H,typename... T>
static typename std::enable_if<std::is_same<typename std::underlying_type<H>::type,uint8_t>::value>::type 
foo(const H&,T&&... t)
{ std::cout << "enumn"; foo(std::forward<T>(t)...); }
*/
};


int main()
{
    S::foo(std::array<int,8>(),5,5L,std::vector<int>{},5L);
}

我想要正确的重载foo被递归调用,基于类型H:

>如果std :: begin(h)被定义为H类型的h,我想要
超载号码1被选择
>如果H是“整数型”,我想要超量2.

这样做是正常的.但是如果我为枚举类型添加了另一个重载(可以尝试取消注释第三个重载),那么我得到:

error: only enumeration types have underlying types

我同意只有枚举有一个底层类型,因此为什么不是第三个重载(与std ::底层类型)得到SFINAE-d?

解决方法

std::underlying_type不是SFINAE友好.尝试访问非枚举类型的std :: underlying_type< T> :: type导致未定义的行为(通常是硬错误),而不是替换失败.

在尝试访问其底层类型之前,您需要先确定所讨论的类型是枚举类型.这样写成一行就是typename std :: enable_if< std :: is_enum< H> :: value,std :: underlying_type< H>> :: type :: type.替换typename std ::底层类型< H> ::类型在你的返回类型与这个可怕的混乱,你得到一个更可怕的混乱,工作:)

如果你发现自己需要经常这样做 – 或者只是不想写typename std :: enable_if< std :: is_same< typename std :: enable_if< std :: is_enum< H> :: value,std :: underlying_type&lt ; H> :: type :: type,uint8_t> :: value> :: type – 您可以编写一个SFINAE友好的底层类型:

template<class T,bool = std::is_enum<T>::value>
struct safe_underlying_type : std::underlying_type<T> {};
template<class T>
struct safe_underlying_type<T,false /* is_enum */> {};

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读