目录
Understanding std::variant Basics
Accessing Values Safely
Use std::get or std::get
Check Active Type with std::holds_alternative
Using std::visit for Type-Safe Dispatch
Handling Errors and Edge Cases
Tips and Best Practices
首页 后端开发 C++ 如何与C中的STD ::变体一起工作

如何与C中的STD ::变体一起工作

Aug 14, 2025 am 11:32 AM
c++

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

How to work with std::variant in C

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 repeated holds_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中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

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

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

热门话题

PHP教程
1596
276
应用程序无法正常启动(0xc0000906)怎么办?解决方案看这里 应用程序无法正常启动(0xc0000906)怎么办?解决方案看这里 Aug 13, 2025 pm 06:42 PM

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

计算机中丢失MSVCP71.dll怎样修复 只需三种方法 计算机中丢失MSVCP71.dll怎样修复 只需三种方法 Aug 14, 2025 pm 08:03 PM

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

如何在C中使用正则表达式 如何在C中使用正则表达式 Aug 12, 2025 am 10:46 AM

要使用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操作员超载示例 C操作员超载示例 Aug 15, 2025 am 10:18 AM

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

c弦向量示例 c弦向量示例 Aug 21, 2025 am 04:02 AM

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

std :: Map vs std :: c in c in c in C std :: Map vs std :: c in c in c in C Aug 14, 2025 pm 06:53 PM

在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

如何与C中的STD ::变体一起工作 如何与C中的STD ::变体一起工作 Aug 14, 2025 am 11:32 AM

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

如何为C项目编写基本的制作费? 如何为C项目编写基本的制作费? Aug 15, 2025 am 11:17 AM

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

See all articles