std::conditional 是 C++ 标准库 <type_traits> 头文件中提供的一个模板工具,用于在编译时根据布尔条件选择两种类型中的一种。其核心功能类似于三元条件运算符(?:),但作用于类型层面而非值层面。
基本语法
#include <type_traits>
template<bool B, typename T, typename F>
struct conditional;
// 特化版本:
template<typename T, typename F>
struct conditional<true, T, F> { using type = T; };
template<typename T, typename F>
struct conditional<false, T, F> { using type = F; };
// 辅助别名模板(C++11 起):
template<bool B, typename T, typename F>
using conditional_t = typename conditional<B, T, F>::type;
- 参数:
B:布尔条件(true或false)。T:当B为true时选择的类型。F:当B为false时选择的类型。
- 成员
type:根据B的值,为T或F。
核心功能
根据布尔条件 B,conditional<B, T, F>::type 会静态地选择 T 或 F:
- 若
B为true,则type是T。 - 若
B为false,则type是F。
实现原理
通过模板特化实现条件选择:
// 主模板(默认处理 B = false)
template<bool B, typename T, typename F>
struct conditional {
using type = F;
};
// 特化模板处理 B = true
template<typename T, typename F>
struct conditional<true, T, F> {
using type = T;
};
使用示例
1. 基本用法
using Type1 = std::conditional<true, int, double>::type; // Type1 = int
using Type2 = std::conditional<false, int, double>::type; // Type2 = double
2. 结合类型特性(Type Traits)
根据类型是否为整数选择不同类型:
template<typename T>
struct SelectType {
using Type = std::conditional_t<std::is_integral_v<T>, int, double>;
};
static_assert(std::is_same_v<SelectType<int>::Type, int>); // 通过
static_assert(std::is_same_v<SelectType<float>::Type, double>); // 通过
3. 条件选择容器类型
template<bool UseVector>
struct ContainerSelector {
using Container = std::conditional_t<UseVector, std::vector<int>, std::list<int>>;
};
ContainerSelector<true>::Container vec; // vec 是 std::vector<int>
ContainerSelector<false>::Container list; // list 是 std::list<int>
与运行时条件的区别
普通 if-else 是运行时的控制流,而 std::conditional 是编译时的类型选择:
// 运行时条件(无法用于类型选择):
if (condition) {
using Type = int;
} else {
using Type = double; // 错误:无法在运行时改变类型
}
// 编译时条件(正确方式):
using Type = std::conditional_t<condition, int, double>;
常见应用场景
- 类型分发(Type Dispatch)
根据类型特性选择不同的实现。template<typename T> struct Wrapper { using Storage = std::conditional_t<std::is_trivially_copyable_v<T>, T, T*>; }; - 优化代码路径
根据编译期条件选择高效的类型或算法。template<bool UseSIMD> struct Algorithm { using DataType = std::conditional_t<UseSIMD, SIMDVector, ScalarVector>; }; - 元编程中的分支逻辑
在模板元编程中实现复杂的分支逻辑。template<typename T> using NestedType = std::conditional_t< std::is_class_v<T>, typename T::value_type, T >;
与 std::enable_if 的区别
| 特性 | std::conditional | std::enable_if |
|———————|—————————————-|—————————————|
| 目的 | 根据条件选择两种类型之一 | 根据条件启用或禁用模板重载 |
| 返回类型 | 直接返回 T 或 F | 条件为真时返回 T,否则无定义 |
| 典型应用场景 | 类型选择、分支逻辑 | SFINAE、模板特化控制 |
总结
std::conditional是编译时类型选择的工具,通过模板特化实现。- 常用于根据布尔条件静态选择类型,提升代码的灵活性和可维护性。
- 结合其他类型特性(如
std::is_integral、std::is_pointer等),可实现复杂的元编程逻辑。