看流星社区

 找回密码
 注册账号
查看: 2103|回复: 0

boost库的使用_tuple

[复制链接]

该用户从未签到

发表于 2017-6-2 11:07:38 | 显示全部楼层 |阅读模式
tuple的使用

一 Boost::tuple

很多的时候我们经常需要为我们的函数返回多个值,一般的做法是通过传入非常量的指针或引用,但是这样的话可能可读性就要差一些,使用者可能需要确切的文档才能确定到底哪个是返回值,为了更好的可读性,我们可以使用class或struct来封装我们要返回的多个值,然后返回封装struct或class,但是使用这种方法的弊端就是增加的程序的代码量,最好的解决办法其实我们可以通过一种匿名的struct或class来解决这个问题。

Boost::tuple就为我们提供了一种类似于匿名struct的方法为我们解决函数的多个返回值的问题。既增强了代码的可读性有不增加代码量。其实在STL中已经有这样的特例,std::pair其实就是boost::tuple的2个参数的特例,对boost::tuple你可以绑定更多的参数,或者你可以迭代实现无限多参数的情况。


二 源码剖析

头文件: "boost/tuple/tuple.hpp",它包含了 tuple 类模板及库的核心部分。

头文件: "boost/tuple/tuple_io.hpp",包含了对 tuple 的输入输出操作符。

头文件: "boost/tuple/tuple_comparison.hpp",包含了 tuple 的关系操作符。

为了方便使用,Tuple 库中有些名字位于名字空间 boost:如 tuple, make_tuple, tie, 和 get.

函数说明:

1)构造函数
2)拷贝构造函数
3)t.get<N>()或get<N>(t) ,取得第N个值
4)make_tuple ,生成tuple
5)tie , 生成都是ref的tuple
6) 重载比较运算符 ,可以直接用来比较
7)重载输入输出运算符 ,可以直接使用IO
8)get_head()和get_tail()函数,用来取得值
9)length<>和element<>用来得到tuple的size和第N个的值类型
10)如果使用boost::TR1,则还可以使用std::tr1::tuple_size(),std::tr1::tuple_element(),分别用来得到tuple的size和第N个值的类型。


三 实例

1)tuple的构造,拷贝构造函数,get成员函数,get全局函数,make_tuple全局函数。

#include<string>
#include<iostream>
#include"boost/tuple/tuple.hpp"

boost::tuples::tuple<int,double>get_values()
{
returnboost::make_tuple(6,12.0);
}
classbase
{
public:
virtual~base(){};
virtualvoidtest()
{
std::cout<<"base::test()";
}
};
classderived:publicbase
{
public:
virtualvoidtest(){std::cout<<"derived::test()";}
};

voidmain()
{
//testforconstructor
boost::tuple<int,double,std::string>triple(42,3.14,"Myfirsttuple!");
boost::tuple<short,int,long>another;
boost::tuple<int,int,double>another2(10);

//testformake_tuple,refandcreffunction
intplain=42;
int&amp;ref=plain;
constint&amp;cref=ref;

boost::tuples::tuple<int>plaint(plain);
plaint=boost::make_tuple(plain);
plaint=boost::make_tuple(ref);
plaint=boost::make_tuple(cref);

boost::tuples::tuple<int&amp;>reft(ref);
boost::make_tuple(boost::ref(plain));
boost::make_tuple(boost::ref(ref));
boost::make_tuple(boost::ref(cref));

boost::tuples::tuple<constint&amp;>creft(cref);
boost::make_tuple(boost::cref(plain));
boost::make_tuple(boost::cref(ref));
boost::make_tuple(boost::cref(cref));


//testforgetfunction
boost::tuple<int,double,std::string>triple2(42,3.14,"Theamazingtuple!");
inti=boost::tuples::get<0>(triple2);
doubled=triple2.get<1>();
std::strings=boost::get<2>(triple2);

//testforfunctionreturntuple
boost::tuples::tuple<int,double>value=get_values();

//testforcopyconstructor
boost::tuple<int,std::string,derived>tup1(-5,"Tuples");
boost::tuple<unsignedint,std::string,base>tup2;
tup2=tup1;
tup2.get<2>().test();
std::cout<<"Interestingvalue:"<<tup2.get<0>()<<"";
constboost::tuple<double,std::string,base>tup3(tup2);
//tup3.get<0>()=3.14;//error,becausetup3isconst

boost::tuples::tuple<int,int,double>tuple1(10,30,20.000);
inthead=tuple1.get_head();
inttailhead=tuple1.get_tail().get_head();
doubletail=tuple1.get_tail().get_tail().get_head();

//forTR1
/*boost::tuples::tuple<double,char,int>tuplesize;
std::tr1::tuple_size();
std::tr1::tuple_element();*/

}



2)使用tie函数模版来生成对ref的绑定的tuple,tuple的比较使用,tuple的输入输出:

#include<string>
#include<iostream>
#include<vector>
#include<algorithm>
#include"boost/tuple/tuple.hpp"
#include"boost/tuple/tuple_comparison.hpp"
#include"boost/tuple/tuple_io.hpp"
template<intIndex>
classelement_less
{
public:
template<typenameTuple>
booloperator()(constTuple&amp;lhs,constTuple&amp;rhs)const
{
returnboost::get<Index>(lhs)<boost::get<Index>(rhs);
}
};
intmain()
{
//Tiersaretuples,whereallelementsareofnon-constreferencetypes.
//Theyareconstructedwithacalltothetiefunctiontemplate
inti;charc;doubled;
boost::tie(i,c,d)=boost::make_tuple(1,"a",5.5);
std::cout<<i<<""<<c<<""<<d<<std::endl;

//testignore
charch;
boost::tie(boost::tuples::ignore,ch)=std::make_pair(1,"a");
std::cout<<ch<<std::endl;

//testforcomparison
boost::tuple<int,std::string>tup1(11,"Match?");
boost::tuple<short,std::string>tup2(12,"Match?");
std::cout<<std::boolalpha;
std::cout<<"Comparison:tup1islessthantup2";
std::cout<<"tup1==tup2:"<<(tup1==tup2)<<"";
std::cout<<"tup1!=tup2:"<<(tup1!=tup2)<<"";
std::cout<<"tup1<tup2:"<<(tup1<tup2)<<"";
std::cout<<"tup1>tup2:"<<(tup1>tup2)<<"";
std::cout<<"tup1<=tup2:"<<(tup1<=tup2)<<"";
std::cout<<"tup1>=tup2:"<<(tup1>=tup2)<<"";
tup2.get<0>()=boost::get<0>(tup1);//tup2=tup1alsoworks
std::cout<<"Comparison:tup1equalstup2";
std::cout<<"tup1==tup2:"<<(tup1==tup2)<<"";
std::cout<<"tup1!=tup2:"<<(tup1!=tup2)<<"";
std::cout<<"tup1<tup2:"<<(tup1<tup2)<<"";
std::cout<<"tup1>tup2:"<<(tup1>tup2)<<"";
std::cout<<"tup1<=tup2:"<<(tup1<=tup2)<<"";
std::cout<<"tup1>=tup2:"<<(tup1>=tup2)<<"";

//testtupleusinginthecontainer
typedefboost::tuple<short,int,long,float,double,longdouble>num_tuple;
std::vector<num_tuple>vec;
vec.push_back(num_tuple(6,2));
vec.push_back(num_tuple(7,1));
vec.push_back(num_tuple(5));
std::sort(vec.begin(),vec.end(),element_less<1>());
std::cout<<"Aftersorting:"<<vec[0].get<0>()<<""<<vec[1].get<0>()<<""<<vec[2].get<0>()<<"";


//testforio
boost::tuple<float,int,std::string>a(1.0f,2,std::string("Howdyfolks!"));
std::cout<<std::endl<<a<<std::endl;

boost::tuple<int,int,int>ii;

std::cin>>ii;
std::cout<<boost::tuples::set_open("[")<<boost::tuples::set_close("]")<<boost::tuples::set_delimiter(":");
std::cout<<ii<<std::endl;

boost::tuples::tuple<int,int,double>tuple1;
inthead=tuple1.get_head();
doubletail=tuple1.get_tail();

}



四 注意

1)函数 make_tuple 类似于 std::make_pair. 缺省情况下,make_tuple 设置元素类型为非const, 非引用的,即是最简单的、根本的参数类

型。

2)为了使一个 tuple 的元素设为引用类型,你要使用函数 boost::ref, 它来自另一个名为 Boost.Ref 的 Boost 库。

3)如果元素需要是 const 引用的,就使用来自 Boost.Ref 的 boost::cref。

4)如果你要使绑定的每个元素变量都为ref,则可以使用tie函数。

五 参考

1)Beyond the C++ Standard Library: An Introduction to Boost
2)boost在线document

原文链接:http://www.cppblog.com/mzty/archive/2007/08/21/30509.html

include <boost/tuple/tuple_io.hpp>
#include <string>
#include <iostream>
using namespace std;
using boost::tuple;
class A{
    int a;
};

A class_a;
boost::tuple<std::string, A> t1("abc", class_a);

int main()
{

    //boost::tuple<int ,int ,double> tuple_2 = boost::tuple::make_tuple<int, int, do
    double d = 2.0;
    A a;
    tuple<int, double&amp;, const A&amp;> t(1, d, a);
    const tuple<int, double&amp;, const A&amp;> ct = t;

    int i = boost::get<0>(t);
    cout<<"the i: "<<i<<endl;

    i = t.get<0>();
    cout<<"the i: "<<i<<endl;
   
    boost::get<1>(t) = 45.34;
    double d_ret = t.get<1>();
    cout<<"the d_ret: "<<d_ret<<endl;

    int tie_i;
    char tie_char;
    double tie_doulbe;
    boost::tuple<int, char, double> tuple_temp(3, 'A', 3.1415);
    boost::tie(tie_i, tie_char, tie_doulbe) = tuple_temp;
    tuple_temp.get<2>() = 3.132434;
    cout<<"the tie_double: "<<tuple_temp.get<2>()<<endl;
    cout<<"the tie_i: "<<tie_i<<endl;
    cout<<"the tie_double: "<<tie_doulbe<<endl;

    char char_temp;
    boost::tie(boost::tuples::ignore, char_temp) = std::make_pair(123, 'a');
    cout<< char_temp<<endl;
  
    tuple<float, int, string> tuple_a(1.3, 2, "abd");
    cout<<tuple_a<<endl;
    cout<<boost::tuples::set_open('[')<<boost::tuples::set_close(']')<<boost::tuples
    return 0;
}


int main()
{

    //boost::tuple<int ,int ,double> tuple_2 = boost::tuple::make_tuple<int, int, double>(5, 10, 23.2);
    double d = 2.0;
    A a;
    tuple<int, double&amp;, const A&amp;> t(1, d, a);
    const tuple<int, double&amp;, const A&amp;> ct = t;

    int i = boost::get<0>(t);
    cout<<"the i: "<<i<<endl;

    i = t.get<0>();
    cout<<"the i: "<<i<<endl;

    boost::get<1>(t) = 45.34;
    double d_ret = t.get<1>();
    cout<<"the d_ret: "<<d_ret<<endl;

    int tie_i;
    char tie_char;
    double tie_doulbe;
    boost::tuple<int, char, double> tuple_temp(3, 'A', 3.1415);
    boost::tie(tie_i, tie_char, tie_doulbe) = tuple_temp;
    tuple_temp.get<2>() = 3.132434;
    cout<<"the tie_double: "<<tuple_temp.get<2>()<<endl;
    cout<<"the tie_i: "<<tie_i<<endl;
    cout<<"the tie_double: "<<tie_doulbe<<endl;

    char char_temp;
    boost::tie(boost::tuples::ignore, char_temp) = std::make_pair(123, 'a');
    cout<< char_temp<<endl;

    tuple<float, int, string> tuple_a(1.3, 2, "abd");
    cout<<tuple_a<<endl;
    cout<<boost::tuples::set_open('[')<<boost::tuples::set_close(']')<<boost::tuples::set_delimiter('\t')<<tuple_a;
    return 0;
}
点击按钮快速添加回复内容: 支持 高兴 激动 给力 加油 苦寻 生气 回帖 路过 感恩
您需要登录后才可以回帖 登录 | 注册账号

本版积分规则

小黑屋|手机版|Archiver|看流星社区 |网站地图

GMT+8, 2024-3-19 18:52

Powered by Kanliuxing X3.4

© 2010-2019 kanliuxing.com

快速回复 返回顶部 返回列表