Boost C++ 库
...在世界上最受尊敬和设计最精巧的 C++ 库项目中之一。
— Herb Sutter 和 Andrei Alexandrescu, C++ Coding Standards
版权所有 © 2002, 2003 Eric Friedman, Itay Maman
版权所有 © 2014-2025 Antony Polukhin
根据 Boost Software License, Version 1.0 分发。(请参阅随附文件 LICENSE_1_0.txt 或访问 https://boost.ac.cn/LICENSE_1_0.txt 复制)
目录
variant 类模板是一个安全、通用、基于栈的判别联合容器,它为以统一的方式操作异构类型集合中的对象提供了一个简单的解决方案。标准容器(如 std::vector)可以被认为是“多值,单类型”,而 variant 则是“多类型,单值”。
boost::variant 的显著特点包括:
boost::apply_visitor 进行编译时类型安全的赋值访问。boost::get 进行运行时检查的显式赋值检索。boost::make_recursive_variant 和 boost::recursive_wrapper 支持递归变体类型。在 C++ 程序开发过程中,程序员经常需要以统一的方式操作几种不同的类型。确实,C++ 通过其 union 关键字直接为这些类型提供了语言支持。
union { int i; double d; } u;
u.d = 3.14;
u.i = 3; // overwrites u.d (OK: u.d is a POD type)
然而,C++ 的 union 结构在面向对象环境中几乎无用。该结构在语言中引入主要是为了保持与 C 的兼容性,C 只支持 POD(Plain Old Data)类型,因此不接受具有非平凡构造或析构的类型。
union {
int i;
std::string s; // illegal: std::string is not a POD type!
} u;
显然需要另一种方法。典型的解决方案是动态分配对象,然后通过一个共同的基类型(通常是虚基类 [Hen01] 或更危险的 void*)来操作它们。然后可以通过多态向下转换(例如 dynamic_cast、boost::any_cast 等)来检索具体类型的对象。
然而,这类解决方案极易出错,原因如下:
此外,即使正确实现,这些解决方案由于使用堆、虚函数调用和多态向下转换,往往会产生相对显著的抽象开销。
类模板以一种安全、直接且高效的方式解决了这些问题。以下示例演示了该类的用法:boost::variant
#include "boost/variant.hpp" #include <iostream> class my_visitor : publicboost::static_visitor<int> { public: int operator()(int i) const { return i; } int operator()(conststd::string& str) const { return str.length(); } }; int main() {boost::variant< int, std::string > u("hello world"); std::cout << u; // output: hello world int result =boost::apply_visitor( my_visitor(), u ); std::cout << result; // output: 11 (i.e., length of "hello world") }