enable_if 对于没有 return 类型的函数
enable_if for functions with no return type pulled in it
我最近遇到了一个有趣的 enable_if
用法版本,它有条件地启用一个函数,可读性稍好一些,因为该函数的 return 类型不是 enable_if
的一部分(请参阅 cleaner_usage
):
#include <type_traits>
using maybe_integral = int /* = or float -- then won't compile */;
using return_type = int;
typename std::enable_if<std::is_integral<maybe_integral>::value, return_type>::type
traditional_usage()
{
return 1;
}
template<typename std::enable_if<std::is_integral<maybe_integral>::value, int>::type = 0>
return_type cleaner_usage()
{
return 2;
}
int main()
{
return traditional_usage() + cleaner_usage();
}
对于失败案例,机制很明确(没有 type
成员)。
但它在其他情况下究竟是如何工作的呢?因为看起来 int
typedef
字段被替换为具有意外分配的模板类型参数。
成功案例:
template<typename std::enable_if<std::is_integral<float>::value, int>::type = 0>
return_type cleaner_usage()
{
return 2;
}
将等同于:
template<int = 0>
return_type cleaner_usage()
{
return 2;
}
这是完全合法的,因为允许某些值类型出现在模板参数上下文中。我相信这些被正式称为非类型模板参数,如§14.1/4所述:
A non-type template-parameter shall have one of the following (optionally cv-qualified) types:
- integral or enumeration type,
- pointer to object or pointer to function,
- lvalue reference to object or lvalue reference to function,
- pointer to member,
std::nullptr_t
.
我最近遇到了一个有趣的 enable_if
用法版本,它有条件地启用一个函数,可读性稍好一些,因为该函数的 return 类型不是 enable_if
的一部分(请参阅 cleaner_usage
):
#include <type_traits>
using maybe_integral = int /* = or float -- then won't compile */;
using return_type = int;
typename std::enable_if<std::is_integral<maybe_integral>::value, return_type>::type
traditional_usage()
{
return 1;
}
template<typename std::enable_if<std::is_integral<maybe_integral>::value, int>::type = 0>
return_type cleaner_usage()
{
return 2;
}
int main()
{
return traditional_usage() + cleaner_usage();
}
对于失败案例,机制很明确(没有 type
成员)。
但它在其他情况下究竟是如何工作的呢?因为看起来 int
typedef
字段被替换为具有意外分配的模板类型参数。
成功案例:
template<typename std::enable_if<std::is_integral<float>::value, int>::type = 0>
return_type cleaner_usage()
{
return 2;
}
将等同于:
template<int = 0>
return_type cleaner_usage()
{
return 2;
}
这是完全合法的,因为允许某些值类型出现在模板参数上下文中。我相信这些被正式称为非类型模板参数,如§14.1/4所述:
A non-type template-parameter shall have one of the following (optionally cv-qualified) types:
- integral or enumeration type,
- pointer to object or pointer to function,
- lvalue reference to object or lvalue reference to function,
- pointer to member,
std::nullptr_t
.