面试题答案
一键面试设计思路
TypeList
容器实现:- 使用模板递归的方式构建类型列表。通过偏特化模板类来终止递归。
SelectType
模板函数:- 利用 SFINAE(Substitution Failure Is Not An Error)技术,结合模板特化和
std::enable_if
来根据索引选择正确的类型并实例化对象。 - 通过模板递归在编译期确定索引对应的类型。
- 利用 SFINAE(Substitution Failure Is Not An Error)技术,结合模板特化和
代码实现
#include <type_traits>
// TypeList 定义
template <typename... Ts>
struct TypeList {};
// 用于获取 TypeList 中类型个数的模板类
template <typename TList, typename = void>
struct TypeListSize;
template <typename... Ts>
struct TypeListSize<TypeList<Ts...>> {
static const size_t value = sizeof...(Ts);
};
// 辅助模板类,用于递归选择类型
template <size_t Index, typename TList, typename = void>
struct SelectTypeHelper;
// 递归终止条件:索引为 0
template <typename Head, typename... Tail>
struct SelectTypeHelper<0, TypeList<Head, Tail...>> {
using type = Head;
static type create() {
return type();
}
};
// 递归选择类型
template <size_t Index, typename Head, typename... Tail>
struct SelectTypeHelper<Index, TypeList<Head, Tail...>,
typename std::enable_if<(Index > 0) && (Index < sizeof...(Tail) + 1)>::type> {
using type = typename SelectTypeHelper<Index - 1, TypeList<Tail...>>::type;
static type create() {
return type();
}
};
// 模板函数,根据索引从 TypeList 中选择类型并实例化对象
template <size_t Index, typename TList>
typename std::enable_if<(Index < TypeListSize<TList>::value),
typename SelectTypeHelper<Index, TList>::type>::type
SelectType() {
return SelectTypeHelper<Index, TList>::create();
}
代码说明
TypeList
:- 是一个模板结构体,用于容纳一系列类型
Ts...
。
- 是一个模板结构体,用于容纳一系列类型
TypeListSize
:- 辅助模板类,用于获取
TypeList
中类型的个数。它利用sizeof...
操作符来计算类型包的大小。
- 辅助模板类,用于获取
SelectTypeHelper
:- 递归模板类,用于在编译期根据索引选择正确的类型。
- 当
Index
为 0 时,选择列表中的第一个类型Head
作为结果类型,并提供create
静态函数来实例化该类型对象。 - 当
Index
大于 0 时,递归地在剩余类型列表TypeList<Tail...>
中选择类型,索引减 1。
SelectType
:- 模板函数,利用
std::enable_if
确保索引在TypeList
的有效范围内,然后调用SelectTypeHelper
的create
函数来实例化选择的类型对象。
- 模板函数,利用
这种实现方式确保了类型安全,由于所有类型选择和索引计算都在编译期完成,运行时效率较高,并且在支持 C++11 及以上标准的编译器下具有较好的兼容性。