std::condition 功能
std::conjunction<Bs...>::value // is true if all Bs... are true, false otherwise
std::condition相当于对一系列类型特性(type traits)做逻辑与(And),例如conjunction<T1,T2,T3,>,如果T1,T2,T3能够萃取出bool类型的value,那么上面试式子相当于T1::value && T2::value && T3::value,按照惯例先看应用场景,condition可以用来判断一系列类型是否相同
#include <iostream>
#include <type_traits>
// func is enabled if all Ts... have the same type as T
template<typename T, typename... Ts>
std::enable_if_t<std::conjunction_v<std::is_same<T, Ts>...>>
func(T, Ts...)
{
std::cout << "all types in pack are T\n";
}
// otherwise
template<typename T, typename... Ts>
std::enable_if_t<!std::conjunction_v<std::is_same<T, Ts>...>>
func(T, Ts...)
{
std::cout << "not all types in pack are T\n";
}
template<typename T, typename... Ts>
constexpr bool all_types_are_same = std::conjunction_v<std::is_same<T, Ts>...>;
static_assert(all_types_are_same<int, int, int>);
static_assert(not all_types_are_same<int, int&, int>);
int main()
{
func(1, 2, 3);
func(1, 2, "hello!");
}
std::condition 实现分析
conjunction的代码非常简洁,但是足够烧脑
template<class...> struct myconjunction : std::true_type { };
template<class B1> struct myconjunction<B1> : B1 { };
template<class B1, class... Bn>
struct myconjunction<B1, Bn...>
: std::conditional<bool(B1::value), myconjunction<Bn...>, B1>::type {};
想要理解这几行代码,首先需要理解递归模板,相信诸位接触过模板元的都知道用模板实现递归计算阶乘的代码
// 主模板
template<int n>
struct factorial1
{
static constexpr const int value = n * factorial1<n - 1>::value;
};
// 终止条件
template<>
struct factorial1<0>
{
static constexpr const int value = 1;
};
int main() {
std::cout << "factorial1: " << factorial1<3>::value << std::endl;
}
上面的模板会递归的展开,展开过程如下,将过程展开,就能理解模板到底干了啥:
template<>
struct factorial1<3>
{
static constexpr const int value = 3 * factorial1<2>::value;
};
template<>
struct factorial1<2>
{
static constexpr const int value = 2 * factorial1<1>::value;
};
template<>
struct factorial1<1>
{
static constexpr const int value = 1 * factorial1<0>::value;
};
我们来看如下例子:bool flag = myconjunction<std::true_type, std::false_type, std::true_type>::value;我们将其递归的展开
//*******myconjunction<std::true_type, std::false_type, std::true_type>::value的实例化
template<>
struct myconjunction<std::true_type, std::false_type, std::true_type > : public std::conditional<true, myconjunction<std::false_type, std::true_type >, std::true_type >::type
{
};
template<>
struct myconjunction<std::true_type, std::false_type, std::true_type > : public myconjunction<std::false_type, std::true_type >
{
};
template<>
struct myconjunction<std::false_type, std::true_type > : public std::false_type
{
};
template<class ... type_parameter_0_0>
struct myconjunction : public std::true_type
{
};
我们来看如下例子:bool flag = myconjunction<std::true_type, std::true_type, std::true_type>::value;我们将其递归的展开
*******myconjunction<std::true_type, std::true_type, std::true_type>::value的实例化
template<>
struct myconjunction<std::true_type, std::true_type, std::true_type > : public std::conditional<true, myconjunction<std::true_type, std::true_type >, std::true_type >::type
{
};
template<>
struct myconjunction<std::true_type, std::true_type > : public std::conditional<true, myconjunction<std::true_type >, std::true_type >::type
{
};
template<>
struct myconjunction<std::true_type > : public std::true_type
{
};
template<class ... type_parameter_0_0>
struct myconjunction : public std::true_type
{
};
可以看到,展开的过程中碰到类型为false的类型就会发生短路(逻辑表达式短路),终止递归。
上面模板中使用到了一个模板conditional,我们可以先记住这个模板的功能是做类型选择。
template <bool b, class T, class U>
struct conditional;
//b为true时,conditional<>::type = T
//b为false时,conditional<>::type = U;