一、std::conditional的定义
这是一个在c++11中提供的一个模板结构体,其定义如下:
//<type_traits> 定义
template< bool B, class T, class F >
struct conditional; (C++11 起)
提供成员 typedef type ,若 B 在编译时为 true 则定义为 T ,或若 B 为 false 则定义为 F 。
添加 conditional 的特化的程序行为未定义。
//说明
成员类型
-----------------------------------------------------------------------------------------
成员类型 定义
-----------------------------------------------------------------------------------------
type 若 B == true 则为 T ,若 B == false 则为 F
辅助类型
----------------------------------------------------------------------------------------
template< bool B, class T, class F >
using conditional_t = typename conditional<B,T,F>::type; (C++14 起)
conditional,本身就是“有条件”的意思,写过Linux条件变量的应该一眼就看得出来。在文档中可以看到它是通过模板第一个参数的值来决定使用其它模板参数。
二、用法
std::conditional的用法还是比较简单的,但是其中有一些小技巧可以达到一些特殊的目的:
1、通过表达式来确定定义的数据类型
这种是标准的文档中的用法,通过第一参数的控制值来决定哪种数据定义被体现出来。
2、可以动态匹配继承
其实这种和第一种没有本质区别,都是通过参数值来定义新类型,但这种有一个好处,可以部分解决多重继承的问题。
其实std::conditional的出现,可以实现一些动态数据类型的转换,比如在开发时使用一个测试数据类,而上线用另外一个。以前可以用宏定义来实现,而现在又多了这个手段,而且无这种方式更容易理解,更安全,更重要的是,它可以调试。其实这些都是在为元编程提供基础构架。
三、例程
先看一个官方文档提供的例程:
#include <iostream>
#include <type_traits>
#include <typeinfo>
int main()
{
typedef std::conditional<true, int, double>::type Type1;
typedef std::conditional<false, int, double>::type Type2;
typedef std::conditional<sizeof(int) >= sizeof(double), int, double>::type Type3;
std::cout << typeid(Type1).name() << '\n'; //int
std::cout << typeid(Type2).name() << '\n'; //double
std::cout << typeid(Type3).name() << '\n'; //double
}
int main()
{
const int tData = 4;
// 定义一个指定字节数的类型
typedef
std::conditional<sizeof(short) == tData, short,
std::conditional<sizeof(int) == tData, int,
std::conditional<sizeof(long) == tData, long,
std::conditional<sizeof(long long) == tData, long long,
void>::type>::type>::type>::type int_my;
std::cout << sizeof(int_my) << '\n'; //4
std::cout << typeid(int_my).name() << std::endl; //int
return 0;
}
再看一个稍微复杂一些的例子:
constexpr int sign = 10;
void TestCond()
{
std::conditional<
(sign > 100), double,
std::conditional<(sign > 80), float, std::conditional<(sign > 40), int, char >::type> ::type
>::type var;
cout << "cur type is:" << typeid(decltype(var)).name() << endl;
}
int main()
{
TestCond();
return 0;
}
再看一个继承的例子:
const bool isOK = false;
class MyTest : public std::conditional<isOK,A,B>::type
{
public:
MyTest() { std::cout << "call MyTest!" << std::endl; }
};
int main()
{
MyTest mt;
return 0;
}
它的运行结果:
call B
call MyTest!
看了上面的应用,基本对它的用法都会了吧。注意,定义中说明了,特化的行为结果未定义。