目录
一、提要
库 Boost.Tuple提供了一个名为 boost::Tuple的类,它是 std::pair 的广义版本。虽然 std::pair 只能存储两个值,但 boost::Tuple允许您选择要存储多少个值。
标准库从 C++11 开始就提供了类 std::Tuple。如果使用支持 C++11 的开发环境,则可以忽略 Boost.Tuple,因为 boost::Tuple和 std::Tuple是相同的。
二、Boost.Tuple示例
例 22.1.boost::Tuple替换std::pair
#include <boost/tuple/tuple.hpp>
#include <boost/tuple/tuple_io.hpp>
#include <string>
#include <iostream>
int main()
{
typedef boost::tuple<std::string, int> animal;
animal a{"cat", 4};
std::cout << a << '\n';
}
要使用boost::tuple
,请包含头文件boost/tuple/tuple.hpp
。要将元组用于流,请包含头文件boost/tuple/tuple_io.hpp
。Boost.元组不提供自动包含所有其他文件的主头文件。
boost::tuple
元组的使用方式与std::pair
相同。在例 22.1 中,创建了一个包含一个 std:: string 类型的值和一个 int 类型的值的元组。这种类型称为动物,它存储动物的名称和腿数。
虽然类型动物的定义可以使用 std::pair,但 boost::tuple
类型的对象可以写入流。为此,必须包含头文件boost/tuple/tuple_io.hpp
,它提供所需的运算符。显示例 22.1(类别 4)。
例 22.2.boost::tuple
作为更好的std::pair
#include <boost/tuple/tuple.hpp>
#include <boost/tuple/tuple_io.hpp>
#include <string>
#include <iostream>
int main()
{
typedef boost::tuple<std::string, int, bool> animal;
animal a{"cat", 4, true};
std::cout << std::boolalpha << a << '\n';
}
例 22.3 存储了一个名称、腿数和一个指示动物是否有尾巴的标志。所有三个值都放置在元组中。执行时,将显示此程序(第 4 类 true)。
您可以使用帮助程序函数 boost::make_tuple() 创建元组,其工作方式类似于 std::pair 的帮助程序函数 std::make_pair()()(参见例 22.3)。
例 22.3.使用提升创建boost::make_tuple()
#include <boost/tuple/tuple.hpp>
#include <boost/tuple/tuple_io.hpp>
#include <iostream>
int main()
{
std::cout.setf(std::ios::boolalpha);
std::cout << boost::make_tuple("cat", 4, true) << '\n';
}
元组还可以包含引用,如例 22.4 所示。
例 22.4.带引用的元组
#include <boost/tuple/tuple.hpp>
#include <boost/tuple/tuple_io.hpp>
#include <boost/ref.hpp>
#include <string>
#include <iostream>
int main()
{
std::string s = "cat";
std::cout.setf(std::ios::boolalpha);
std::cout << boost::make_tuple(boost::ref(s), 4, true) << '\n';
}
值 4 和 true 由值传递,因此直接存储在元组内,但是,第一个元素是对字符串 s 的引用。来自 Boost.Ref 的函数boost::ref() 用于创建引用。要创建常量引用,请使用boost::cref()。
通常,您可以使用标准库中的C++::ref()而不是 boost::ref()。但是,示例 22.4 使用 boost::ref(), 因为只有 Boost.Ref 提供了写入标准输出的运算符。
std::pair 首先使用成员变量,然后使用第二个成员变量来提供访问。由于元组没有固定数量的元素,因此必须以不同的方式处理访问。
例 22.5.读取元组的元素
#include <boost/tuple/tuple.hpp>
#include <string>
#include <iostream>
int main()
{
typedef boost::tuple<std::string, int, bool> animal;
animal a = boost::make_tuple("cat", 4, true);
std::cout << a.get<0>() << '\n';
std::cout << boost::get<0>(a) << '\n';
}
有两种方法可以访问元组中的值。您可以调用成员函数 get(),也可以将元组传递给独立函数 boost::get()。在这两种情况下,元组中相应元素的索引都必须作为模板参数提供。例 22.5 在这两种情况下都访问元组 a 的第一个元素,因此显示 cat 两次。
指定无效索引会导致编译器错误,因为在编译时检查索引有效性。
成员函数 get() 和独立函数 boost::get() 都返回一个引用,允许您更改元组内的值。
例 22.6.编写元组的元素
#include <boost/tuple/tuple.hpp>
#include <boost/tuple/tuple_io.hpp>
#include <string>
#include <iostream>
int main()
{
typedef boost::tuple<std::string, int, bool> animal;
animal a = boost::make_tuple("cat", 4, true);
a.get<0>() = "dog";
std::cout << std::boolalpha << a << '\n';
}
示例 22.6 修改了动物的名称,从而显示(狗 4 true)。
Boost.元组还定义了比较运算符。若要比较元组,请包括头文件boost/tuple/tuple_comparison.hpp。
Example 22.7. 元组比较
#include <boost/tuple/tuple.hpp>
#include <boost/tuple/tuple_comparison.hpp>
#include <string>
#include <iostream>
int main()
{
typedef boost::tuple<std::string, int, bool> animal;
animal a1 = boost::make_tuple("cat", 4, true);
animal a2 = boost::make_tuple("shark", 0, true);
std::cout << std::boolalpha << (a1 != a2) << '\n';
}
示例显示为 true,因为元组 a1 和 a2 不同。
头文件boost/tuple/tuple_comparison.hpp
还包含其他比较运算符(如大于)的定义,该运算符执行词典比较。
Boost.tuple支持一种称为层的特定形式的元组。层是元组,其元素都是引用类型。它们可以使用函数boost::tie()构造。
例 22.8.创建一个具有提升的层boost::tie()
#include <boost/tuple/tuple.hpp>
#include <boost/tuple/tuple_io.hpp>
#include <string>
#include <iostream>
int main()
{
typedef boost::tuple<std::string&, int&, bool&> animal;
std::string name = "cat";
int legs = 4;
bool tail = true;
animal a = boost::tie(name, legs, tail);
name = "dog";
std::cout << std::boolalpha << a << '\n';
}
示例 22.8 创建了一个层 a,它由对变量名称、腿和尾部的引用组成。修改变量名称时,将同时修改层。
例 22.8 也可以使用 boost::make_tuple() 和 boost::ref() 编写(参见例 22.9)。
例 22.9.创建没有boost::tie()
的层
#include <boost/tuple/tuple.hpp>
#include <boost/tuple/tuple_io.hpp>
#include <string>
#include <iostream>
int main()
{
typedef boost::tuple<std::string&, int&, bool&> animal;
std::string name = "cat";
int legs = 4;
bool tail = true;
animal a = boost::make_tuple(boost::ref(name), boost::ref(legs),
boost::ref(tail));
name = "dog";
std::cout << std::boolalpha << a << '\n';
}
boost::tie()
缩短了语法。此函数还可用于解压缩元组。在例 22.10 中,函数返回的元组的各个值立即存储在变量中。
例 22.10.从元组中解压缩函数的返回值
#include <boost/tuple/tuple.hpp>
#include <string>
#include <iostream>
boost::tuple<std::string, int> new_cat()
{
return boost::make_tuple("cat", 4);
}
int main()
{
std::string name;
int legs;
boost::tie(name, legs) = new_cat();
std::cout << name << ", " << legs << '\n';
}
boost::tie() 将字符串“cat”和数字 4 存储在变量名称和分支中,这两个字符串都作为元组从 new_cat() 返回。