std::variant::holds_alternative用于安全检查variant当前是否持有指定类型,需显式指定模板参数,返回bool;正确用法是先检查再std::get,且需防范valueless_by_exception状态。

std::variant::holds_alternative 用来判断当前存储的是哪个类型
std::variant::holds_alternative 是一个编译期确定、运行时安全的类型检查工具。它不抛异常,也不触发重载解析,只单纯告诉你:这个 std::variant 对象此刻是否正保存着你指定的类型。
常见错误是把它和 std::get<T> 混用,比如在没确认类型就直接 std::get<int>(v) —— 这会触发 std::bad_variant_access 异常。正确做法永远是先 holds_alternative,再 get。
- 必须传入具体类型(如
int、std::string),不能传变量或 auto - 类型必须是
std::variant的合法备选类型之一,否则编译失败 - 返回
bool,值为true表示当前持有该类型,false表示没有(包括空状态)
怎么写才能避免模板推导失败
调用 holds_alternative 时,类型参数必须显式写出,不能依赖模板自动推导。因为它的签名是 template<class T> bool holds_alternative(const variant& v) noexcept;,而 T 不参与函数参数推导。
典型误写:holds_alternative(v)(缺模板参数)或 holds_alternative<decltype(x)>(v)(x 类型可能不是 v 的合法备选项)。
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
立即学习“C++免费学习笔记(深入)”;
- 正确写法:
std::holds_alternative<int>(v)、std::holds_alternative<std::string>(v) - 如果类型名太长,可用
using别名简化,但别用auto或decltype替代模板实参 - 注意命名空间:它是
std::命名空间下的非成员函数,不是variant的成员函数
和 std::get 配合使用的典型模式
最常见用途就是“先检查、再取值”。尤其在处理用户输入、配置解析、序列化反解等场景中,variant 存了多种可能类型,你得逐个分支处理。
std::variant<int, double, std::string> v = "hello";
if (std::holds_alternative<int>(v)) {
int i = std::get<int>(v); // 安全
} else if (std::holds_alternative<double>(v)) {
double d = std::get<double>(v);
} else if (std::holds_alternative<std::string>(v)) {
std::string s = std::get<std::string>(v);
}
- 每个
if分支里才能安全调用对应类型的std::get - 不要用
switch直接对variant操作 —— 它没有整型索引接口(index()虽有但不推荐作为主逻辑) - 若分支太多,考虑用
std::visit+ lambda,但holds_alternative更轻量、更直观
空 variant 和 valueless_by_exception 状态下 behavior
当 std::variant 处于 valueless_by_exception 状态(例如某次赋值抛异常导致构造失败),所有 holds_alternative<T> 都返回 false,包括对所有合法备选类型的检查。
这和“空”不同——std::variant 本身没有默认构造出“空值”的概念;只有首次初始化失败后才会进入该状态。实际项目中极少遇到,但一旦发生,holds_alternative 仍能可靠返回 false,不会崩溃。
- 可通过
v.valueless_by_exception()显式检查该状态 - 此时调用任何
std::get都会抛std::bad_variant_access - 如果你的代码需要容错,建议在所有
holds_alternative检查前加一句!v.valueless_by_exception()
holds_alternative 是少数几个能安全探测它的手段之一。

















