0

0

C++的std::variant如何访问_C++17中std::visit与std::get的使用方法

裘德小鎮的故事

裘德小鎮的故事

发布时间:2025-12-03 15:45:07

|

763人浏览过

|

来源于php中文网

原创

std::variant支持std::get和std::visit两种访问方式:std::get适用于已知类型时直接提取值,需配合std::holds_alternative避免异常;std::visit通过函数对象或lambda实现类型安全的多态访问,适合处理多种类型的分支逻辑,支持单个或多个variant的联合操作,更安全且易于扩展。

c++的std::variant如何访问_c++17中std::visit与std::get的使用方法

在C++17中,std::variant 是一个类型安全的联合体(union),可以保存多种类型中的某一种值。要访问其中的内容,主要使用 std::getstd::visit 两种方式。它们各有适用场景,下面分别说明用法。

使用 std::get 访问特定类型的值

std::get 用于直接获取 variant 中存储的某种类型的值,前提是你知道当前存储的是哪种类型,否则会抛出 std::bad_variant_access 异常。

支持通过类型或索引访问:

  • std::get<Type>(variant) —— 按类型获取
  • std::get<index>(variant) —— 按类型在模板参数列表中的位置获取

示例:

立即学习C++免费学习笔记(深入)”;

#include <variant>
#include <iostream>

int main() {
    std::variant<int, double, std::string> v = 3.14;

    // 按类型获取
    if (v.index() == 1) {
        double val = std::get<double>(v);
        std::cout << "Value: " << val << "\n";
    }

    // 按索引获取(double 是第1个索引)
    double val2 = std::get<1>(v);
    std::cout << "By index: " << val2 << "\n";

    // 错误访问会抛异常
    try {
        std::string s = std::get<std::string>(v); // 当前不是 string
    } catch (const std::bad_variant_access&) {
        std::cout << "Not a string!\n";
    }
}

建议先用 v.index()std::holds_alternative 判断类型:

if (std::holds_alternative<double>(v)) {
    std::cout << std::get<double>(v);
}

使用 std::visit 实现类型安全的多态访问

当 variant 可能包含多种类型,且需要根据不同类型执行不同逻辑时,std::visit 是更安全、更灵活的选择。它会自动调用对应类型的处理函数,无需手动判断。

Nanonets
Nanonets

基于AI的自学习OCR文档处理,自动捕获文档数据

下载

基本语法:

std::visit(可调用对象, variant...);

可调用对象可以是 lambda、函数对象或普通函数。常用写法是使用泛型 lambda 或结构体重载 operator()

示例:使用泛型 lambda 处理不同类型

#include <variant>
#include <vector>
#include <iostream>

int main() {
    std::vector<std::variant<int, double, std::string>> vec = {10, 3.14, "hello"};

    for (auto& v : vec) {
        std::visit([](auto& arg) {
            std::cout << arg << " (" << typeid(arg).name() << ")\n";
        }, v);
    }
}

如果你需要为每种类型写不同的逻辑,可以定义专门的 visitor 结构体:

struct MyVisitor {
    void operator()(int i) const {
        std::cout << "Integer: " << i << "\n";
    }
    void operator()(double d) const {
        std::cout << "Double: " << d << "\n";
    }
    void operator()(const std::string& s) const {
        std::cout << "String: " << s << "\n";
    }
};

// 使用
std::variant<int, double, std::string> v = "world";
std::visit(MyVisitor{}, v);

std::visit 还支持多个 variant 同时访问(适用于函数参数数量相同的场景):

std::variant<int, double> v1 = 5;
std::variant<int, double> v2 = 3.14;

std::visit([](auto& a, auto& b) {
    std::cout << a + b << "\n";
}, v1, v2);

std::get 与 std::visit 的选择建议

  • 当你确定类型,或者已通过 std::holds_alternative 检查后,使用 std::get 直接提取值,适合简单场景。
  • 当你需要对 variant 的所有可能类型进行分支处理,尤其是逻辑较复杂时,优先使用 std::visit,代码更安全、清晰,避免异常风险。
  • std::visit 更符合函数式风格,也更容易扩展新类型。

基本上就这些。合理使用 std::get 和 std::visit,可以让 variant 的使用既安全又高效。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
java多态详细介绍
java多态详细介绍

本专题整合了java多态相关内容,阅读专题下面的文章了解更多详细内容。

27

2025.11.27

golang结构体相关大全
golang结构体相关大全

本专题整合了golang结构体相关大全,想了解更多内容,请阅读专题下面的文章。

490

2025.06.09

golang结构体方法
golang结构体方法

本专题整合了golang结构体相关内容,请阅读专题下面的文章了解更多。

202

2025.07.04

c语言union的用法
c语言union的用法

c语言union的用法是一种特殊的数据类型,它允许在相同的内存位置存储不同的数据类型,union的使用可以帮助我们节省内存空间,并且可以方便地在不同的数据类型之间进行转换。使用union时需要注意对应的成员是有效的,并且只能同时访问一个成员。本专题为大家提供union相关的文章、下载、课程内容,供大家免费下载体验。

129

2023.09.27

lambda表达式
lambda表达式

Lambda表达式是一种匿名函数的简洁表示方式,它可以在需要函数作为参数的地方使用,并提供了一种更简洁、更灵活的编码方式,其语法为“lambda 参数列表: 表达式”,参数列表是函数的参数,可以包含一个或多个参数,用逗号分隔,表达式是函数的执行体,用于定义函数的具体操作。本专题为大家提供lambda表达式相关的文章、下载、课程内容,供大家免费下载体验。

215

2023.09.15

python lambda函数
python lambda函数

本专题整合了python lambda函数用法详解,阅读专题下面的文章了解更多详细内容。

192

2025.11.08

Python lambda详解
Python lambda详解

本专题整合了Python lambda函数相关教程,阅读下面的文章了解更多详细内容。

61

2026.01.05

TypeScript类型系统进阶与大型前端项目实践
TypeScript类型系统进阶与大型前端项目实践

本专题围绕 TypeScript 在大型前端项目中的应用展开,深入讲解类型系统设计与工程化开发方法。内容包括泛型与高级类型、类型推断机制、声明文件编写、模块化结构设计以及代码规范管理。通过真实项目案例分析,帮助开发者构建类型安全、结构清晰、易维护的前端工程体系,提高团队协作效率与代码质量。

1

2026.03.13

Python异步编程与Asyncio高并发应用实践
Python异步编程与Asyncio高并发应用实践

本专题围绕 Python 异步编程模型展开,深入讲解 Asyncio 框架的核心原理与应用实践。内容包括事件循环机制、协程任务调度、异步 IO 处理以及并发任务管理策略。通过构建高并发网络请求与异步数据处理案例,帮助开发者掌握 Python 在高并发场景中的高效开发方法,并提升系统资源利用率与整体运行性能。

37

2026.03.12

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
SQL 教程
SQL 教程

共61课时 | 4.3万人学习

10分钟--Midjourney创作自己的漫画
10分钟--Midjourney创作自己的漫画

共1课时 | 0.1万人学习

Midjourney 关键词系列整合
Midjourney 关键词系列整合

共13课时 | 0.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号