用于无符号类型选择的 SFINAE
SFINAE for unsigned type selection
我正在尝试使用 SFINAE
检查类型是否具有 unsigned
等价物。虽然它似乎适用于 int
和 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
除外)或枚举类型,提供T
对应的无符号整数类型成员typedef类型,具有相同的 cv 限定符。
如果T
是signed
或unsigned
char
,short
,int
,long
, long long
;提供了此列表中对应于 T
的 unsigned
类型。
若T
为枚举类型或char
,wchar_t
,char8_t
(C++20起),char16_t
, char32_t
;提供了与 T
具有相同 sizeof
的最小秩的 unsigned
整数类型。
否则,行为未定义。 (直到 C++20)
否则,程序是病式的。 (C++20 起)
我正在尝试使用 SFINAE
检查类型是否具有 unsigned
等价物。虽然它似乎适用于 int
和 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
除外)或枚举类型,提供T
对应的无符号整数类型成员typedef类型,具有相同的 cv 限定符。如果
T
是signed
或unsigned
char
,short
,int
,long
,long long
;提供了此列表中对应于T
的unsigned
类型。若
T
为枚举类型或char
,wchar_t
,char8_t
(C++20起),char16_t
,char32_t
;提供了与T
具有相同sizeof
的最小秩的unsigned
整数类型。
否则,行为未定义。 (直到 C++20)
否则,程序是病式的。 (C++20 起)