C++模板元一生之敌之:std::conjunction

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;
  • 6
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值