template<class = enable_if_t<...>> 是做什么的?
What does template<class = enable_if_t<...>> do?
我一直在阅读 STL 文件以学习格式化代码的更好方法,并学习提高效率的技巧。我一直在阅读线程文件,但我无法弄清楚某些代码的作用。
template<class _Fn,
class... _Args,
class = enable_if_t<!is_same<decay_t<_Fn>, thread>::value>>
explicit thread(_Fn&& _Fx, _Args&&... _Ax)
{ // construct with _Fx(_Ax...)
...
}
std::enable_if_t
是
template<bool _Test,
class _Ty = void>
using enable_if_t = typename enable_if<_Test, _Ty>::type;
template<class _Ty>
struct enable_if<true, _Ty>
{ // type is _Ty for _Test
using type = _Ty;
};
该代码在 thread 和 str1common STL 中均受版权保护。
我唯一的问题是 class = enable_if_t<...>
有什么作用?
寻找 S.F.I.N.A.E.: "Substitution Failure Is Not An Error".
查看 std::enable_if
的可能实现(std::enable_if_t
只是一个助手 using
,引入了 C++14,以更简单的方式访问 type
)
template<bool B, class T = void>
struct enable_if {};
template<class T>
struct enable_if<true, T> { typedef T type; };
是这样iff(当且仅当)模板布尔值(第一个模板参数)是true
,定义std::enable_if<...>::type
(使用第二个模板参数中的类型;void
如果未表示)。
为简单起见,在您的示例中有这个
template<class _Fn,
class... _Args,
class = enable_if_t<!is_same<decay_t<_Fn>, thread>::value>>
explicit thread(_Fn&& _Fx, _Args&&... _Ax)
{ // construct with _Fx(_Ax...)
...
}
enable_if_t
(即 typename std::enable_if<...>::type)
可用,前提是第一个值 (!std::is_same<typename std::decay<_Fn>::type, thread>::value
) 是 true
.
即:
若!std::is_same<typename std::decay<_Fn>::type, thread>::value
为true
,则代入class = enable_if_t<!is_same<decay_t<_Fn>, thread>::value>>
,实现功能
如果!std::is_same<typename std::decay<_Fn>::type, thread>::value
是false
,替换class = enable_if_t<!is_same<decay_t<_Fn>, thread>::value>>
失败,函数没有实现但是这个不是错误 (SFINAE)。
为什么语言允许这样做?
因为,通过示例,您可以实现函数的两个版本
template<class _Fn,
class... _Args, // vvvv true case
class = enable_if_t<true == is_same<decay_t<_Fn>, thread>::value>>
explicit thread(_Fn&& _Fx, _Args&&... _Ax)
{ /* do something */ }
template<class _Fn,
class... _Args, // vvvvv false case
class = enable_if_t<false == is_same<decay_t<_Fn>, thread>::value>>
explicit thread(_Fn&& _Fx, _Args&&... _Ax)
{ /* do something else */ }
建议:搜索 SFINAE 并研究它,因为它是现代 C++ 的重要组成部分。
我一直在阅读 STL 文件以学习格式化代码的更好方法,并学习提高效率的技巧。我一直在阅读线程文件,但我无法弄清楚某些代码的作用。
template<class _Fn,
class... _Args,
class = enable_if_t<!is_same<decay_t<_Fn>, thread>::value>>
explicit thread(_Fn&& _Fx, _Args&&... _Ax)
{ // construct with _Fx(_Ax...)
...
}
std::enable_if_t
是
template<bool _Test,
class _Ty = void>
using enable_if_t = typename enable_if<_Test, _Ty>::type;
template<class _Ty>
struct enable_if<true, _Ty>
{ // type is _Ty for _Test
using type = _Ty;
};
该代码在 thread 和 str1common STL 中均受版权保护。
我唯一的问题是 class = enable_if_t<...>
有什么作用?
寻找 S.F.I.N.A.E.: "Substitution Failure Is Not An Error".
查看 std::enable_if
的可能实现(std::enable_if_t
只是一个助手 using
,引入了 C++14,以更简单的方式访问 type
)
template<bool B, class T = void>
struct enable_if {};
template<class T>
struct enable_if<true, T> { typedef T type; };
是这样iff(当且仅当)模板布尔值(第一个模板参数)是true
,定义std::enable_if<...>::type
(使用第二个模板参数中的类型;void
如果未表示)。
为简单起见,在您的示例中有这个
template<class _Fn,
class... _Args,
class = enable_if_t<!is_same<decay_t<_Fn>, thread>::value>>
explicit thread(_Fn&& _Fx, _Args&&... _Ax)
{ // construct with _Fx(_Ax...)
...
}
enable_if_t
(即 typename std::enable_if<...>::type)
可用,前提是第一个值 (!std::is_same<typename std::decay<_Fn>::type, thread>::value
) 是 true
.
即:
若
!std::is_same<typename std::decay<_Fn>::type, thread>::value
为true
,则代入class = enable_if_t<!is_same<decay_t<_Fn>, thread>::value>>
,实现功能如果
!std::is_same<typename std::decay<_Fn>::type, thread>::value
是false
,替换class = enable_if_t<!is_same<decay_t<_Fn>, thread>::value>>
失败,函数没有实现但是这个不是错误 (SFINAE)。
为什么语言允许这样做?
因为,通过示例,您可以实现函数的两个版本
template<class _Fn,
class... _Args, // vvvv true case
class = enable_if_t<true == is_same<decay_t<_Fn>, thread>::value>>
explicit thread(_Fn&& _Fx, _Args&&... _Ax)
{ /* do something */ }
template<class _Fn,
class... _Args, // vvvvv false case
class = enable_if_t<false == is_same<decay_t<_Fn>, thread>::value>>
explicit thread(_Fn&& _Fx, _Args&&... _Ax)
{ /* do something else */ }
建议:搜索 SFINAE 并研究它,因为它是现代 C++ 的重要组成部分。