天天看点

(C++模板编程):std::conditionalstd::conditional

std::conditional

【标准库中的实现方式】
template <bool b, class T, class U> //泛化版本
struct conditional 
{ 
	using type = T; //type类型别名
};

template <class T, class U>
struct conditional<false, T, U> 
{
	using type = U;
};
           
  • 很显然,bool值只要为false就执行特化版本,即type = U;bool值为true才去执行泛化版本,即type = T;
  • 如果b值为true,那么type这个类型别名所代表的类型就是conditional类模板的第二个模板参数T,否则就是conditional类模板第三个模板参数U。
    • 所以这个类模板看起来表达的是一种if-then-else逻辑。
  • 其实现逻辑不难联想到三目运算符    bool b :type = T   ? type =U;
【调用测试】
std::conditional<true, int, double>::type tmp1; 
std::conditional<false, int, double>::type tmp2;

cout << "tmp1的类型为:" << typeid(decltype(tmp1)).name() << endl;
cout << "tmp2的类型为:" << typeid(decltype(tmp2)).name() << endl;
           
【输出】
(C++模板编程):std::conditionalstd::conditional
【总结】
  • 根据给进来的布尔值不同,做到了让一个变量可能会有多种不同的类型的效果——范例中变量可能是int类型,也可能是double类型。
【引例】
int i = 35;
if (i > 100)
{
	cout << "i > 100" << endl;
}
else
{
	if (i > 80)
	{
		cout << "i > 80并且 <=100" << endl;
	}
	else
	{
		if (i > 40)
		{
			cout << "i > 40并且 <= 80" << endl;
		}
		else
		{
			cout << "i <= 40" << endl;
		}
	}
}
           
  • std::conditional类模板其逻辑类似是一种if-then-else
【需求】
  • 定义一个名字叫做tsvar的变量,根据某个常量(取名为j)值的不同,tsvar变量的类型也不同:
    • a)j如果大于100,那么tsvar的类型是double类型,
    • b)j如果在80-100之间,那么tsvar的类型是float类型,
    • c)j如果在40-80之间,那么tsvar的类型是int类型,
    • d)j如果不超过40,那么tsvar的类型是char类型。
【实现】
constexpr int j = 35; //假设给进去35

std::conditional<
	(j > 100), double,  //值>100,tsvar是double,
	std::conditional<
		(j > 80), float, //值在80-100之间,那么tsvar是float类型。
		std::conditional<
			(j > 40), int,  //值在40-80之间,那么tsvar是int类型。
			char       //值不超过40,tsvar是char类型
		>::type
	> ::type
>::type   tsvar;

out << "tsvar的类型为:" << typeid(decltype(tsvar)).name() << endl; //char
           
  • 总结: std::conditional虽然使用不复杂,但是他通常适合实现真或者假两种分支,如果要支持多分支,那么可以看到,写出来的代码不好看。