文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

C++BoostVariant示例超详细讲解

2022-11-13 19:31

关注

一、提要

        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内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     801人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     348人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     311人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     432人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     220人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯