1 conditional_t
编译时的条件分支
参数:
_Cond
:是能够编译时得到结果的条件表达式_Iftrue
:如果 _Cond 为 true,::type
为 _Iftrue_Iffalse
:如果 _Cond 为 true,::type
为 _Iffalse
template<bool _Cond, typename _Iftrue, typename _Iffalse>
using conditional_t = typename conditional<_Cond, _Iftrue, _Iffalse>::type;
template<bool _Cond, typename _Iftrue, typename _Iffalse>
struct conditional
{ typedef _Iftrue type; };
// Partial specialization for false.
template<typename _Iftrue, typename _Iffalse>
struct conditional<false, _Iftrue, _Iffalse>
{ typedef _Iffalse type; };
2 enable_if
条件成立,则正确执行。条件不成立,则,发生编译时错误。
可以根据条件的不同,控制函数的可见性。也就是说,条件成立,函数可以正确编译和调用,条件不成立,函数不可编译。
参数:
_Cond
:是能够编译时得到结果的条件表达式_Tp
:如果 _Cond 为 true,::type
为 _Tp。如果 _Cond 为false, 就没有::type
,会发生编译时错误。
template<bool _Cond, typename _Tp = void>
using enable_if_t = typename enable_if<_Cond, _Tp>::type;
template<bool, typename _Tp = void>
struct enable_if
{ };
// Partial specialization for true.
template<typename _Tp>
struct enable_if<true, _Tp>
{ typedef _Tp type; };
比如:optional类中,有这么一段代码
template<typename... _Args>
_GLIBCXX20_CONSTEXPR //修饰函数为constexpr属性
enable_if_t<is_constructible_v<_Tp, _Args...>, _Tp&>
emplace(_Args&&... __args)
noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
{
this->_M_reset();
this->_M_construct(std::forward<_Args>(__args)...);
return this->_M_get();
}
enable_if_t<is_constructible_v<_Tp, _Args...>, _Tp&>
约束 只有在 _Tp 类型可以由 _Args 参数构造时,该返回值类型才有效。 它不会直接影响函数的行为,但会影响函数是否可以被正确编译和调用。
多个类型的共同检查
分别对应于逻辑上的 &&、||和!
1 __and_
类似逻辑运算符 and, 对多个条件进行同时检查。如果全部满足,则返回true,否则,返回false
通过模板的递推展开,来对每一个类型进行检查。
template<typename... _Bn>
inline constexpr bool __and_v = __and_<_Bn...>::value;
2 __or_
类似逻辑运算符 or, 对多个条件进行同时检查。如果有一个满足,则返回true,否则,返回false
和 __and_
类似,也是模板递推展开
template<typename... _Bn>
inline constexpr bool __or_v = __or_<_Bn...>::value;
3 __not_
类似逻辑运算符 not, 对单个条件进行检查。如果条件为false, 返回true, 否则,返回false
template<typename _Pp>
struct __not_
: public __bool_constant<!bool(_Pp::value)>
{ };