1.1 type_traits

If else的结构

有时候想在编译的时候,实现这样的效果,就是根据传入的值来决定需要产生的类型。
比如:

void function(type X, type Y) {
// if a == true 定义类型X
constexpr bool a = true/false;
if (a) {
X var;
} else {
Y var;
}
// 如果想在这里引用var,应该怎么办?
// ?? 实际上是不能在这里用的。
}

一种解决办法是,写一个父类,然后把X/Y声明成Base的子类。

class Base {
};
class X : public Base {
};
class Y : public Base {
};
void function(bool a, type X, type Y) {
Base * b = nullptr;
if (a) {
b = new X();
} else {
b = new Y();
}
b.接口调用();
}

但是这么写会很烦人:

  1. 引入了不必要的父类
  2. XY可能已经有自己的父类
  3. X/Y如果还需要与Z在其他地方生成这样的代码关系,那还得生成一个父类

这个时候,采用面向对象的方法代码会写得比较丑,那么一种办法是引入模板偏特化。

template<typename bool, typename If, typename Then>
struct cond {
typedef If type;
};
template<typename If, typename Then>
struct cond<false, If, Then>{
typedef Then type;
};

使用方式

class X{};
class Y{};
cond<true, X, Y>::type 此时为 X
cond<false, X, Y>::type 就是Y

Example

#include <iostream>
template<bool Bool, typename If, typename Then>
struct cond {
typedef If type;
};
template<typename If, typename Then>
struct cond<false, If, Then>{
typedef Then type;
};
class If {
public:
static void print(void) {
std::cout << "If" << std::endl;
}
};
class Then {
public:
static void print(void) {
std::cout << "Then" << std::endl;
}
};
int main(void) {
// 需要注意的是,true/false这里需要是编译期间就可以决定的常量。
// 不能写成bool a = true, 然后cond<a, If, Then>这样。
cond<true, If, Then>::type::print();
cond<false, If, Then>::type::print();
return 0;
}

这里相当于在进行类型运算:

if (constexpr true) {
return type=X;
} else {
return type=Y;
}

这里就需要引出后面要介绍的模板元编程。