std::any用于存储任意类型值,适合类型未知的场景,如配置管理;std::variant是类型安全的联合体,适用于预定义类型的多选一情况,性能更高、更安全,推荐优先使用。

在C++17中引入的std::any和std::variant都是用于处理不同类型数据的工具,但它们的设计目的和使用场景有明显区别。理解它们各自的用途和正确用法,能帮助你在泛型编程、配置管理、解析器等场景中做出合适选择。
std::any:存储任意类型的值
std::any 可以保存任意类型的单个值,类似“万能容器”。它适用于你不知道或不关心具体类型,但需要临时存储某个对象的场景。
特点:
可存放任何可复制的类型类型安全:取值时必须指定正确类型,否则抛出异常性能开销较大(涉及堆分配和类型信息存储)
基本用法示例:
立即学习“C++免费学习笔记(深入)”;
#include #include #includeint main() {std::any data = 42; // 存整数data = std::string{"hello"}; // 换成字符串
if (data.type() == typeid(std::string)) { std::cout << std::any_cast(data) << 'n';}try { auto num = std::any_cast(data); // 错误类型 → 抛异常} catch (const std::bad_any_cast&) { std::cout << "类型转换失败n";}return 0;
}
也可以使用 any_cast(ptr) 返回指针,避免异常:
if (auto* str = std::any_cast(&data)) { std::cout << *str << 'n';}
std::variant:类型受限的多选一联合体
std::variant 是一个“类型安全的union”,只能保存预定义的几种类型之一。它适合当你知道可能的类型集合,且每次只持有一种的情况。
特点:
类型集合在定义时确定内存大小为最大类型的大小(通常在栈上分配)支持访问者模式(visit)进行类型分发处理比 std::any 更高效、更安全
基本用法示例:
立即学习“C++免费学习笔记(深入)”;
#include #include #includeusing VarType = std::variant;
int main() {VarType v = 42;v = 3.14;v = std::string{"text"};
// 检查当前类型if (std::holds_alternative(v)) { std::cout << std::get(v) << 'n';}// 使用 visit 分发处理std::visit([](auto& val) { std::cout << "类型=" << typeid(val).name() << ", 值=" << val << 'n';}, v);return 0;
}
注意:访问错误类型会抛出 std::bad_variant_access 异常。也可用 std::get_if(&v) 获取指针方式安全访问。
如何选择 any 还是 variant?
根据实际需求判断:
用 std::any 当你需要真正“任意类型”的灵活性,比如插件系统、反射模拟、配置项存储等。用 std::variant 当你知道所有可能的类型,比如表达式求值中的数字/字符串、JSON-like结构、状态机返回值等。优先考虑 std::variant,因为它更高效、类型更明确,编译期就能检查很多问题。
例如,实现一个简易JSON类,可以用 variant 表示基本类型:
using JsonValue = std::variant<std::nullptr_t, bool, int, double, std::string, std::vector, std::map>;
基本上就这些。std::any 和 std::variant 都是为了让C++在保持类型安全的前提下,拥有更强的动态行为表达能力。合理使用,能显著提升代码的清晰度和健壮性。
以上就是c++++中的std::any和std::variant有什么用_c++ std::any与std::variant使用方法的详细内容,更多请关注创想鸟其它相关文章!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1477482.html
微信扫一扫
支付宝扫一扫