面试题答案
一键面试设计思路
- 定义类型列表:使用模板参数包来表示类型列表。
- 定义条件判断:通过模板特化来定义类型需要满足的条件。
- 实现筛选逻辑:利用 SFINAE(Substitution Failure Is Not An Error),在模板实例化过程中,如果类型不满足条件,替换失败但不报错,从而实现筛选。
- 展示筛选结果:通过特化模板类,将满足条件的类型保留,不满足的类型剔除。
核心代码实现
#include <iostream>
#include <type_traits>
// 定义一个类型特征用于条件判断,这里以是否为整数类型为例
template <typename T>
struct IsIntegerType : std::is_integral<T> {};
// 类型列表节点
template <typename T, typename... Ts>
struct TypeList {
using Head = T;
using Tail = TypeList<Ts...>;
};
// 空类型列表
template <>
struct TypeList<> {};
// 筛选器模板类
template <typename List, template <typename> class Condition>
struct TypeFilter;
// 特化:空类型列表
template <template <typename> class Condition>
struct TypeFilter<TypeList<>, Condition> {
using Result = TypeList<>;
};
// 特化:非空类型列表,当前类型满足条件
template <typename T, typename... Ts, template <typename> class Condition>
std::enable_if_t<Condition<T>::value, void>
append_type(TypeList<T, Ts...>&, TypeList<T>& result) {
result = {T{}};
append_type(TypeList<Ts...>{}, result.Tail);
}
// 特化:非空类型列表,当前类型不满足条件
template <typename T, typename... Ts, template <typename> class Condition>
std::enable_if_t<!Condition<T>::value, void>
append_type(TypeList<T, Ts...>&, TypeList<> &result) {
append_type(TypeList<Ts...>{}, result);
}
// 特化:非空类型列表
template <typename T, typename... Ts, template <typename> class Condition>
struct TypeFilter<TypeList<T, Ts...>, Condition> {
using Result = typename decltype([] {
TypeList<> result;
append_type(TypeList<T, Ts...>{}, result);
return result;
})::type;
};
// 打印类型列表
template <typename List>
struct PrintTypeList;
template <>
struct PrintTypeList<TypeList<>> {
static void print() {}
};
template <typename T, typename... Ts>
struct PrintTypeList<TypeList<T, Ts...>> {
static void print() {
std::cout << typeid(T).name() << std::endl;
PrintTypeList<TypeList<Ts...>>::print();
}
};
int main() {
using MyList = TypeList<int, float, double, char>;
using FilteredList = TypeFilter<MyList, IsIntegerType>::Result;
PrintTypeList<FilteredList>::print();
return 0;
}
上述代码实现了一个简单的类型筛选器 TypeFilter
,它从类型列表 MyList
中筛选出整数类型。通过 IsIntegerType
这个条件判断模板类,结合 SFINAE 技术,在编译期完成筛选操作,并通过 PrintTypeList
打印出筛选后的类型列表。