当前位置:主页 > c/c++教程 > C++ Boost Variant

C++ Boost Variant示例超详细讲解

发布:2023-03-12 14:00:01 59


给大家整理了相关的编程文章,网友莘逸美根据主题投稿了本篇教程内容,涉及到C++、Boost、Variant、C++、Boost、Variant示例、C++ Boost Variant相关内容,已被724网友关注,如果对知识点想更进一步了解可以在下方电子资料中获取。

C++ Boost Variant

一、提要

        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 
#include 
int main()
{
  boost::variant 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 
#include 
#include 
int main()
{
  boost::variant v;
  v = 3.14;
  std::cout << boost::get(v) << '\n';
  v = 'A';
  std::cout << boost::get(v) << '\n';
  v = "Boost";
  std::cout << boost::get(v) << '\n';
}

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

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

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

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

#include 
#include 
#include 
int main()
{
  boost::variant 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 
#include 
#include 
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 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 
#include 
#include 
struct output : public boost::static_visitor<>
{
  template 
  void operator()(T t) const { std::cout << t << '\n'; }
};
int main()
{
  boost::variant 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内容请搜索码农之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持码农之家!


参考资料

相关文章

  • C++ Boost Container库示例详细讲解

    发布:2023-03-09

    Boost是为C++语言标准库提供扩展的一些C++程序库的总称。Boost库是一个可移植、提供源代码的C++库,作为标准库的后备,是C++标准化进程的开发引擎之一,是为C++语言标准库提供扩展的一些C++程序库的总称


  • 详解C++中动态内存管理和泛型编程

    发布:2023-03-05

    这篇文章主要为大家详细介绍了C++中动态内存管理和泛型编程的相关资料,文中示例代码讲解详细,对我们学习C++具有一定帮助,感兴趣的小伙伴快跟随小编一起学习一


  • C++ Boost Bimap示例详细讲解

    发布:2023-03-09

    Boost是为C++语言标准库提供扩展的一些C++程序库的总称。Boost库是一个可移植、提供源代码的C++库,作为标准库的后备,是C++标准化进程的开发引擎之一,是为C++语言标准库提供扩展的一些C++程序库的总称


  • C++中cout输出中文信息乱码问题及解决

    发布:2023-03-12

    这篇文章主要介绍了C++中cout输出中文信息乱码问题及解决,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教


  • 浅谈C++的几种从键盘输入方式

    发布:2023-01-11

    给网友朋友们带来一篇关于C++的教程,今天小编就为大家分享一篇浅谈C++的几种从键盘输入方式,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧


  • C++使用回溯法解决黄金矿工问题

    发布:2023-03-03

    在矩阵中考察回溯算法,分为任意起点、左上角开始等情况。从而有不同的模板,其实区别就是直接开始还是每个坐标都去尝试,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习吧


  • 深入了解C++函数重载解析策略

    发布:2023-03-05

    这篇文章主要为大家详细介绍了C++中函数重载的解析策略,文中的示例代码讲解详细,对我们学习C++有一定帮助,感兴趣的小伙伴可以了解一下


  • Lua和C/C++互相调用实例分析

    发布:2022-06-23

    给网友们整理关于C++的教程,今天小编就为大家分享一篇关于Lua和C/C++互相调用实例分析,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧


网友讨论