c++ - SFINAE 用于无符号类型选择
问题描述
我试图用来SFINAE
检查一个类型是否有unsigned
等价物。虽然它似乎对int
and有效bool
,但对float
. 从错误来看,似乎没有定义某种类型。问题是如果模板参数enable_if
格式不正确,为什么不将其从重载选择中删除?
#include <type_traits>
#include <iostream>
template <typename T>
std::enable_if_t<sizeof(std::make_unsigned<T>), bool> hasUnsigned(T x)
{
return true;
}
bool hasUnsigned(...)
{
return false;
}
int main()
{
float x; // If it's int, or char, it below displays true
std::cout << std::boolalpha << hasUnsigned(x) << std::endl;
}
错误float
In file included from has_unsigned.cc:1:
/usr/include/c++/10/type_traits: In instantiation of ‘struct std::make_unsigned<float>’:
has_unsigned.cc:5:18: required by substitution of ‘template<class T> std::enable_if_t<(sizeof (std::make_unsigned<_Tp>) != 0), bool> hasUnsigned(T) [with T = float]’
has_unsigned.cc:18:48: required from here
/usr/include/c++/10/type_traits:1826:62: error: invalid use of incomplete type ‘class std::__make_unsigned_selector<float, false, false>’
1826 | { typedef typename __make_unsigned_selector<_Tp>::__type type; };
| ^~~~
/usr/include/c++/10/type_traits:1733:11: note: declaration of ‘class std::__make_unsigned_selector<float, false, false>’
1733 | class __make_unsigned_selector;
| ^~~~~~~~~~~~~~~~~~~~~~~~
解决方案
您正在使用make_unsigned
无效类型(见下文),这会使行为未定义或程序格式错误。更好的方法是检查它是否是整数:
std::enable_if_t<std::is_integral_v<T>, bool>
如果
T
是整数(除了bool
)或枚举类型,则提供成员 typedef 类型,它是对应于 的无符号整数类型T
,具有相同的 cv 限定符。如果
T
是signed
,unsigned
char
,short
,int
, ;long
_ 提供了此列表中对应long long
的类型。unsigned
T
If
T
是枚举类型或char
,wchar_t
,char8_t
(C++20 起),char16_t
,char32_t
;unsigned
提供具有相同等级的最小sizeof
整数类型T
。
否则,行为未定义。(C++20 前)
否则,程序是非良构的。(C++20 起)
推荐阅读
- c# - 如何在 Azure DevOps 上为发布服务器项目而不是客户端的 Blazor WebAssembly 托管应用程序创建构建管道?
- r - 条形图 - R 中的直方图
- php - php,如何将 int 打包为签名的 64 位 little-endian 字符串?
- json - 字符串列表的 Spring Boot 输入验证仅返回第一个无效值
- swift - 如何添加长度不同的两个数组的值?
- c# - 如何统一更新运行时的图像?
- asp.net - 如何为具有相同根文件夹的 2 个域设置 web.config
- html - Chrome / Windows 中的 CSS 3D 变换交叉点故障
- firebase - Firebase 数据库保护项目所有者的数据
- python - 在 Peewee 中禁用缓存