如何与C中的STD ::变体一起工作
std::variant 是 C 17 引入的类型安全联合体,能安全地持有多个指定类型之一的值,通过 std::get、std::holds_alternative、std::visit 和 std::get_if 等方法实现安全访问与类型检查,结合 std::monostate 可模拟可选值,推荐使用 std::visit 进行类型分发并避免大型类型列表以提升可维护性,最终确保类型安全和异常安全。
Working with std::variant
in C involves safely handling a type-safe union that can hold one of several specified types at a time. It was introduced in C 17 as a modern, safer alternative to raw unions. Here's how to use it effectively.
Understanding std::variant Basics
std::variant
is a template that can store one value from a fixed list of types. Only one type is active at a time, and the variant keeps track of which one.
#include <variant> #include <string> #include <iostream> std::variant<int, std::string, double> v; v = 42; // v holds an int v = "hello"; // v holds a std::string
By default, the variant is initialized with the first type in the list (if it's default-constructible). In the example above, v
starts as an int(0)
.
You can also explicitly construct it:
std::variant<int, std::string> v = std::string("hello");
Accessing Values Safely
Never assume which type is stored. Use proper methods to check or retrieve values.
Use std::get<T>
or std::get<I>
You can retrieve the value if you know the type or index:
std::get<int>(v); // if v holds int std::get<0>(v); // same, by index
But if the type doesn't match, it throws std::bad_variant_access
. So always check first.
Check Active Type with std::holds_alternative
if (std::holds_alternative<int>(v)) { std::cout << "int: " << std::get<int>(v); } else if (std::holds_alternative<std::string>(v)) { std::cout << "string: " << std::get<std::string>(v); }
This is safe and clear for simple cases.
Using std::visit
for Type-Safe Dispatch
The most powerful way to work with std::variant
is std::visit
, which applies a callable to the active value.
std::visit([](auto&& arg) { using T = std::decay_t<decltype(arg)>; if constexpr (std::is_same_v<T, int>) { std::cout << "int: " << arg; } else if constexpr (std::is_same_v<T, std::string>) { std::cout << "string: " << arg; } else if constexpr (std::is_same_v<T, double>) { std::cout << "double: " << arg; } }, v);
This is clean and avoids runtime type checks when possible (thanks to if constexpr
).
You can also define a visitor struct:
struct Printer { void operator()(int i) const { std::cout << "int: " << i; } void operator()(const std::string& s) const { std::cout << "string: " << s; } void operator()(double d) const { std::cout << "double: " << d; } }; std::visit(Printer{}, v);
This works because the visitor must be callable for every possible alternative in the variant.
Handling Errors and Edge Cases
- Assignment: Assigning a new value changes the active type automatically.
- No value? Unlike
std::optional
,std::variant
always holds a value (of one of the types). - Exception safety: Construction and assignment may throw if the target type's operations throw.
- Empty variant? There’s no “empty” state unless you include
std::monostate
for emulating optional behavior in a variant.
Example with std::monostate
:
std::variant<std::monostate, int, std::string> maybe_value; // Initially holds std::monostate → "empty"
Tips and Best Practices
- Keep variant types small and related logically (e.g., AST node types, message variants).
- Prefer
std::visit
over repeatedholds_alternative
checks when doing complex logic. - Avoid very large variant lists — they become hard to maintain and may impact performance.
- Make sure all visitor overloads are defined; otherwise, compilation fails.
- Use
std::get_if<T>(&v)
to get a pointer to the value if it’s the right type — useful for checking without exceptions:
if (auto* p = std::get_if<int>(&v)) { std::cout << "Got int: " << *p; }
This is especially useful in performance-critical code where exceptions are avoided.
Basically, std::variant
works best when combined with std::visit
and proper type-safe access patterns. It's a key tool for modern C when you need sum types or type-safe unions.
以上是如何与C中的STD ::变体一起工作的详细内容。更多信息请关注PHP中文网其他相关文章!

热AI工具

Undress AI Tool
免费脱衣服图片

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

打开软件或游戏时,突然出现“应用程序无法正常启动(0xc0000906)”的提示,许多用户都会感到困惑,不知从何下手。实际上,这类错误大多源于系统文件损坏或运行库缺失。别急着重装系统,本文为你提供几种简单有效的解决方法,助你快速恢复程序运行。一、0xc0000906错误到底是什么?错误代码0xc0000906属于Windows系统常见的启动异常,通常表示程序在运行时无法加载必要的系统组件或运行环境。该问题常出现在运行大型软件或游戏时,主要原因可能包括:必要的运行库未安装或遭到破坏。软件安装包不完

电脑提示“计算机中丢失MSVCP71.dll”,通常是因为系统缺少关键运行组件,导致软件无法正常加载。本文将深入解析该文件的功能、报错根源,并提供三种高效解决方案,助你快速恢复程序运行。一、MSVCP71.dll是什么?MSVCP71.dll属于MicrosoftVisualC 2003的核心运行库文件,属于动态链接库(DLL)类型,主要用于支持C 编写的程序调用标准函数、STL模板及基础数据处理模块。许多2000年代初开发的应用程序和经典游戏都依赖此文件运行。一旦该文件缺失或损坏,系

要使用C 中的正则表达式,需包含头文件,并利用其提供的函数进行模式匹配和文本处理。1.使用std::regex_match进行全字符串匹配,仅当整个字符串符合模式时返回true;2.使用std::regex_search在字符串中查找任意位置的匹配;3.使用std::smatch提取捕获组,通过matches[0]获取完整匹配,matches[1]及后续获取子匹配;4.使用std::regex_replace替换匹配的文本,支持用$1、$2等引用捕获组;5.可在构造regex时添加icase(

C 中的运算符重载允许为自定义类型赋予标准运算符新行为,1.通过成员函数重载 返回新对象;2.重载 =修改当前对象并返回引用;3.友元函数重载

std::vector的基本用法包括:1.声明vector;2.使用push_back()添加元素;3.用初始化列表初始化;4.用范围for循环遍历;5.通过索引或back()访问元素;6.直接赋值修改元素;7.用pop_back()删除末尾元素;8.调用size()获取元素数量;操作时推荐使用constauto&避免拷贝,预分配reserve()提升性能,并注意访问前检查非空,该数据结构是处理字符串列表的高效首选方式。

在C 中,std::map和std::unordered_map的选择取决于具体需求。1.底层结构不同:std::map基于红黑树实现,键按顺序存储,默认升序,查找和插入复杂度为O(logn);std::unordered_map使用哈希表,无序,平均查找和插入复杂度为O(1),最坏为O(n)。2.插入性能与内存开销:map插入需维护树结构,效率较低;unordered_map插入更快但占用更多内存,可通过reserve()优化。3.自定义比较函数:map支持自定义比较函数,unordered

std::variant是C 17引入的类型安全联合体,能安全地持有多个指定类型之一的值,通过std::get、std::holds_alternative、std::visit和std::get_if等方法实现安全访问与类型检查,结合std::monostate可模拟可选值,推荐使用std::visit进行类型分发并避免大型类型列表以提升可维护性,最终确保类型安全和异常安全。

AbasicMakeFileAutomatesc compilationByByDefindingruleswithtargets和commands.2.KeyComponentsIncludeVariablesLikeCXX,CXXFlags,cxxflags,target,srcs,srcs,srcs,srcs,srcs,objstosimplifyConfiguration.3.AptertNrules.3.aptertnrules(compiles)comptiles $ compiles $:%
