跳转到内容

创建自己的类型特征(type traits)

类型特征一般都是 struct,一般都有一个数据成员value,如果类型符合条件,那么value的值就是 true,否则就是 false。

模仿标准库预置的类型特征,将自己的类型特征定义为结构(struct)模板,接收类型作为模板参数,将判断结果作为 bool 型静态成员 value 的值。

例子

编写一个类型特征is_renderable,对于类Fish其 value 为 true,对于其余类其 value 为 false。

首先,对于所有类型,让该类型特征的 value 都是 false。

template<typename T>
struct is_renderable {
static const bool value{false};
};

对于类Fish或其他我们想要的类型,可以针对它们专门化(specialize)类型特征模板,让类型特征针对这些类型,其 value 为 true。

template<typename T>
struct is_renderable {
static const bool value{false};
};
template<>
struct is_renderable<Fish> {
static const bool value{true};
};

可以让我们自己编写的类型特征is_renderable继承自std::false_type(想让value的值为false时)或std::true_type(想让value的值为true时),这样会让速度更快一些。

template<typename>
struct is_renderable : std::false_type {};
template<>
struct is_renderable<Fish> : std::true_type {};

标准库里的类型特征一般都会有带后缀_v(对于值)或_t(对于类型)的一个东西,来方便地提供结果。就像std::is_integral_v<T>等价于std::is_integral<T>::value。能否为自己编写的类型特征实现相同的东西?这可以通过变量模板(value template)实现。

template<typename>
struct is_renderable : std::false_type {};
template<>
struct is_renderable<Fish> : std::true_type {};
template <typename T>
constexpr bool is_renderable_v{is_renderable<T>::value};

完整代码:

/*
* 编写函数 func(),判断参数类型是否为 int,如果是,打印一条消息;如果不是,打印另一条消息。
*/
#include <iostream>
#include <type_traits>
class Fish {
public:
static void render() {
std::cout << "Fish: ><((((`>";
}
};
template<typename>
struct is_renderable : std::false_type {};
template<>
struct is_renderable<Fish> : std::true_type {};
template <typename T>
constexpr bool is_renderable_v{is_renderable<T>::value};
template <typename T>
void render(T param) {
if constexpr (is_renderable_v<T>) {
param.render();
} else {
std::cout << "\nNot Renderable";
}
}
int main() {
Fish myFish;
render(myFish); // renderable
render(42); // not renderable
}

参考