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;
【输出】
【总结】
- 根据给进来的布尔值不同,做到了让一个变量可能会有多种不同的类型的效果——范例中变量可能是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虽然使用不复杂,但是他通常适合实现真或者假两种分支,如果要支持多分支,那么可以看到,写出来的代码不好看。