返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >C++BoostVariant示例超详细讲解
  • 539
分享到

C++BoostVariant示例超详细讲解

C++BoostVariantC++BoostVariant示例 2022-11-13 19:11:25 539人浏览 独家记忆
摘要

目录一、提要二、示例一、提要         Boost.Variant 提供了一个类似于 uNIO&

一、提要

        Boost.Variant 提供了一个类似于 uNIOn 的名为 boost::variant 的类。您可以将不同类型的值存储在 boost::variant 变量中。在任何时候只能存储一个值。分配新值时,旧值将被覆盖。但是,新值的类型可能与旧值不同。唯一的要求是这些类型必须作为模板参数传递给 boost::variant,这样它们才能为 boost::variant 变量所知。

        boost::variant 支持任何类型。例如,可以将 std::string 存储在 boost::variant 变量中——这在 c++11 之前使用联合是不可能的。在 C++11 中,对联合的要求被放宽了。现在联合可以包含一个 std::string。因为 std::string 必须使用placement new 进行初始化,并且必须通过显式调用析构函数来销毁,所以使用 boost::variant 仍然有意义,即使在 C++11 开发环境中也是如此。

二、示例

        示例 24.1。使用 boost::variant

#include <boost/variant.hpp>
#include <string>
int main()
{
  boost::variant<double, char, std::string> v;
  v = 3.14;
  v = 'A';
  v = "Boost";
}

        boost::variant 在 boost/variant.hpp 中定义。因为 boost::variant 是一个模板,所以必须至少指定一个参数。一个或多个模板参数指定支持的类​​型。在示例 24.1 中,v 可以存储类型为 double、char 或 std::string 的值。但是,如果您尝试将 int 类型的值分配给 v,则生成的代码将无法编译。

        示例 24.2。使用 boost::get() 访问 boost::variant 中的值

#include <boost/variant.hpp>
#include <string>
#include <iOStream>
int main()
{
  boost::variant<double, char, std::string> v;
  v = 3.14;
  std::cout << boost::get<double>(v) << '\n';
  v = 'A';
  std::cout << boost::get<char>(v) << '\n';
  v = "Boost";
  std::cout << boost::get<std::string>(v) << '\n';
}

        要显示 v 的存储值,请使用独立函数 boost::get()(参见示例 24.2)。

        boost::get() 期望对应变量的有效类型之一作为模板参数。指定无效类型将导致运行时错误,因为类型验证不会在编译时进行。

        boost::variant 类型的变量可以写入标准输出流等流,从而绕过运行时错误的风险(参见示例 24.3)。

        示例 24.3。在流上直接输出 boost::variant

#include <boost/variant.hpp>
#include <string>
#include <iostream>
int main()
{
  boost::variant<double, char, std::string> v;
  v = 3.14;
  std::cout << v << '\n';
  v = 'A';
  std::cout << v << '\n';
  v = "Boost";
  std::cout << v << '\n';
}

        对于类型安全的访问,Boost.Variant 提供了一个名为 boost::apply_visitor() 的函数。

        示例 24.4。使用访问者来提升::variant

#include <boost/variant.hpp>
#include <string>
#include <iostream>
struct output : public boost::static_visitor<>
{
  void operator()(double d) const { std::cout << d << '\n'; }
  void operator()(char c) const { std::cout << c << '\n'; }
  void operator()(std::string s) const { std::cout << s << '\n'; }
};
int main()
{
  boost::variant<double, char, std::string> v;
  v = 3.14;
  boost::apply_visitor(output{}, v);
  v = 'A';
  boost::apply_visitor(output{}, v);
  v = "Boost";
  boost::apply_visitor(output{}, v);
}

        作为其第一个参数,boost::apply_visitor() 期望从 boost::static_visitor 派生的类的对象。此类必须为它所作用的 boost::variant 变量使用的每种类型重载 operator()。因此,在示例 24.4 中,运算符重载了 3 次,因为 v 支持 double、char 和 std::string 类型。

        boost::static_visitor 是一个模板。 operator() 的返回值类型必须指定为模板参数。如果运算符没有返回值,则不需要模板参数,如示例中所示。

        传递给 boost::apply_visitor() 的第二个参数是一个 boost::variant 变量。

        boost::apply_visitor() 自动为第一个参数调用 operator() ,该参数与当前存储在第二个参数中的值的类型相匹配。这意味着每次调用 boost::apply_visitor() 时,示例程序都会使用不同的重载运算符——首先是用于 double 的运算符,然后是用于 char 的运算符,最后是用于 std::string 的运算符。

        boost::apply_visitor() 的优点不仅在于自动调用正确的运算符。此外,boost::apply_visitor() 确保为 boost::variant 变量支持的每种类型都提供了重载运算符。如果未定义三个重载运算符之一,则无法编译代码。

        如果重载的运算符在功能上是等效的,则可以使用模板简化代码(参见示例 24.5)。

        示例 24.5。使用带有 boost::variant 函数模板的访问者

#include <boost/variant.hpp>
#include <string>
#include <iostream>
struct output : public boost::static_visitor<>
{
  template <typename T>
  void operator()(T t) const { std::cout << t << '\n'; }
};
int main()
{
  boost::variant<double, char, std::string> v;
  v = 3.14;
  boost::apply_visitor(output{}, v);
  v = 'A';
  boost::apply_visitor(output{}, v);
  v = "Boost";
  boost::apply_visitor(output{}, v);
}

        因为 boost::apply_visitor() 确保了编译时代码的正确性,所以应该优先于 boost::get()。

到此这篇关于C++ Boost Variant示例超详细讲解的文章就介绍到这了,更多相关C++ Boost Variant内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: C++BoostVariant示例超详细讲解

本文链接: https://lsjlt.com/news/171056.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • C++BoostVariant示例超详细讲解
    目录一、提要二、示例一、提要         Boost.Variant 提供了一个类似于 unio&...
    99+
    2022-11-13
    C++ Boost Variant C++ Boost Variant示例
  • C++BoostPropertyTree示例超详细讲解
    目录一、提要二、应用示例练习一、提要 借助类 boost::property_tree::ptree,Boost.PropertyTree 提供了一个树结构来存储键/值对。树形结构意...
    99+
    2022-11-13
    C++ Boost PropertyTree C++ Boost PropertyTree示例
  • C++BoostOptional示例超详细讲解
    目录一、概述二、Boost.Optional一、概述 数据结构类似于容器,因为它们可以存储一个或多个元素。但是,它们与容器不同,因为它们不支持容器通常支持的操作。例如,使用本部分介绍...
    99+
    2022-11-13
    C++ Boost Optional C++ Boost Optional示例
  • C++ 超详细示例讲解list的使用
    目录一、list的介绍list的介绍二、list的使用2.1 list的构造函数2.2 list迭代器的使用2.3 list相关的容量大小相关的函数2.4 list数据的访问相关的函...
    99+
    2024-04-02
  • C++BoostBimap示例详细讲解
    目录一、提要二、示例练习一、提要 库 Boost.Bimap 基于 Boost.MultiIndex 并提供了一个无需先定义即可立即使用的容器。该容器类似于 std::map,但支持...
    99+
    2022-11-13
    C++ Boost Bimap C++ Bimap库
  • C++BoostUuid超详细讲解
    目录一、说明二、Boost.Uuid库示例和代码一、说明 Boost.Uuid 为 UUID 提供生成器。 UUID 是不依赖于中央协调实例的通用唯一标识符。例如,没有数据库存储所有...
    99+
    2022-12-08
    C++ Boost Uuid C++ Uuid标识符
  • C++BoostUtility超详细讲解
    目录一、说明二、Boost.Utility库示例和代码一、说明 Boost.Utility 库是杂项、有用的类和函数的集合,它们太小而无法在独立库中维护。虽然实用程序很小并且可以快速...
    99+
    2022-12-08
    C++ Boost Utility C++ Utility库
  • C++BoostContainer库示例详细讲解
    目录一、关于Boost.Container二、Boost.Container示例一、关于Boost.Container Boost.Container Boost.Container...
    99+
    2022-11-13
    C++ Boost Container C++ Container库
  • C++ Boost Assign超详细讲解
    目录说明Exercise说明 Boost.Assign Boost.Assign 库提供了帮助函数来初始化容器或向容器添加元素。如果需要将许多元素存储在一个容器中,这些函数尤其有用。...
    99+
    2022-12-09
    C++ Boost Assign C++ Assign库
  • C++超详细讲解泛型
    目录1.了解泛型编程2.函数模板2.1简单示例2.2多个模板参数2.3模板实例化2.4模板和普通函数同时存在2.5函数模板不支持定义和声明分离3.类模板3.1简单示例3.2成员函数声...
    99+
    2024-04-02
  • Vue超详细讲解重试机制示例
    重试指的是当加载出错时,有能力重新发起加载组件的请求。 异步组件加载失败后的重试机制,与请求服务端接口失败后的重试机制一样。所以,先来讨论接口请求失败后的重试机制是如何实现的, 为此...
    99+
    2023-01-05
    Vue重试机制 Vue重试
  • C++超详细讲解标准库
    目录一、有趣的重载二、C++ 标准库三、小结一、有趣的重载 操作符 << 的原生意义是按位左移,例:1 <<2; 其意义是将整数 1 按位左移2位,即:000...
    99+
    2024-04-02
  • 【笔记】Hawkes Process:超详细带示例的讲解
    最近准备学Hawkes Process, 但是找遍了百度,b站,谷歌和youtube,都没有找到通俗易懂的讲解。今天终于在拆老师(ChatGPT)的帮助下搞懂了!关于使用ChatGPT进行自学的Prompt可以看之前的笔记:【笔记】 如...
    99+
    2023-09-03
    python 算法 数据分析 学习方法
  • C++超详细讲解智能指针
    目录一、内存泄漏-永恒的话题二、深度思考三、智能指针分析四、小结一、内存泄漏-永恒的话题 动态申请堆空间,用完后不归还C++ 语言中没有垃圾回收的机制指针无法控制所指堆空间的生命周期...
    99+
    2024-04-02
  • C++超详细讲解函数对象
    目录一、客户需求二、存在的问题三、解决方案四、函数对象五、小结一、客户需求 编写一个函数 函数可以获得斐波那契数列每项的值每调用一次返回一个值函数可根据需要重复使用 下面来看第一个...
    99+
    2024-04-02
  • C++超详细讲解字符串类
    目录一、历史遗留问题二、解决方案三、标准库中的字符串类四、字符串循环右移五、小结一、历史遗留问题 C 语言不支持真正意义上的字符串C 语言用字符数组和一组函数实现字符串操作C 语言不...
    99+
    2024-04-02
  • C++超详细讲解稀疏矩阵
    目录稀疏矩阵矩阵与稀疏矩阵的定义稀疏矩阵的转置详细思路思路一思路二稀疏矩阵的乘法详细思路稀疏矩阵 矩阵与稀疏矩阵的定义 Q:什么是矩阵 A:数学上,一个矩阵由 m 行 n 列的元素组...
    99+
    2024-04-02
  • C++超详细讲解函数重载
    目录1 函数重载的定义2 构成函数重载的条件3 编译器调用重载函数的准则4 函数重载的注意事项4.1 避开重载带有指定默认值参数的函数4.2 注意函数重载遇上函数指针4.3 C++编...
    99+
    2024-04-02
  • C++超详细讲解析构函数
    目录特性析构函数处理自定义类型编译器生成的默认析构函数特性 析构函数是特殊的成员函数 特征如下: 析构函数名是~类名;无参数无返回值;一个类有且只有一个析构函数;对象声明周期结束,编...
    99+
    2024-04-02
  • C++超详细讲解构造函数
    目录类的6个默认成员函数构造函数特性编译器生成的默认构造函数成员变量的命名风格类的6个默认成员函数 如果我们写了一个类,这个类我们只写了成员变量没有定义成员函数,那么这个类中就没有函...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作