#include <boost/tuple/tuple.hpp> #include <boost/tuple/tuple_io.hpp>
#include <boost/tuple/tuple_comparison.hpp>
//tuple(元组),他和std::pair类似,只是他不仅仅存储一对数据,可以存储无限多个数据
//tuple使其支持流的输出,需要包含 #include <boost/tuple/tuple_io.hpp>
typedef boost::tuple<std::string,std::string,int> person;
std::stringstream strstream;
person per("hello","hi",32);
strstream << per;
TRACE("%s\n",strstream.str().c_str());//(hello hi 32)
//boost::make_tuple
{
person per=boost::make_tuple("hello","hi",32);
strstream.str("");//stringstream 清除缓冲区 只能使用strstream.str("");如果使用strstream.clear(),strstream.str().clear() 也是么有效果的
strstream<<per;
TRACE("%s\n",strstream.str().c_str());
string szName="name";
//引用值传递
person per2=boost::make_tuple(boost::ref(szName),"hi",32);
strstream.str("");strstream<<per2;
TRACE("%s\n",strstream.str().c_str());
}
//如何访问tuple的元素
{
person per=boost::make_tuple("hello","hi",32);
strstream.str("");
strstream<< per.get<0>();
TRACE("%s\n",strstream.str().c_str());//hello
//第二种访问方式
strstream.str("");
strstream<< boost::get<2>(per);
TRACE("%s\n",strstream.str().c_str());//32
//get() 和 boost::get() 都会返回一个引用值,所以我们可以对其进行修改值
boost::get<2>(per)=33;
strstream.str("");
strstream<<boost::get<2>(per);
TRACE("%s\n",strstream.str().c_str());//33
}
//比较操作,需要包含 boost/tuple/tuple_comparison.hpp
{
person p1 = boost::make_tuple("AA", "BB", 43);
person p2 = boost::make_tuple("AA", "BB", 43);
TRACE("%d\n",p1 != p2);
}
//boost::tie 使用,比较特殊,他可以引用变量,变量一旦修改他也修改了
{
//这里定义的记得使用引用类型
typedef boost::tuple<std::string&, std::string&, int&> person2;
std::string firstname = "AA";
std::string secondname = "BB";
int shoesize = 43;
//person p = boost::make_tuple(boost::ref(firstname), boost::ref(surname), boost::ref(shoesize)); //如果不使用boost::tie可以使用原生的替换
person2 p = boost::tie(firstname, secondname, shoesize);
firstname="DD";
secondname = "CC";
shoesize=44;
strstream.str("") ;strstream.clear();
strstream << p;
TRACE("%s\n",strstream.str().c_str());//(DD CC 44)
}
{
string szData;int nData;
boost::tie(szData,nData)=func();
TRACE("%s,%d\n",szData.c_str(),nData);//Test test,1024
}
1.boost::variant
boost::variant<double,char,std::string> v;
v=3.14;
v='a';
v="jks";//最后压入了string
double v1=boost::get<double>(v);//这里会抛出一个异常,boost::variant 以最后一个为准
char v2=boost::get<char>(v);
string v3=boost::get<string>(v);
boost::variant<double,char,std::string> v;
v=3.14;
v='a';
v="jks";//最后压入了string
string v3=boost::get<string>(v);//提取正确
boost::variant<double,char,std::string> v;
//正确运行如下
v=3.14;
double v1=boost::get<double>(v);
v='a';
char v2=boost::get<char>(v);
v="jks";
string v3=boost::get<string>(v);
boost::variant<double,char,std::string> v;
v=3.14;
v='a';
v="jks";//最后压入了string
try
{
double v1=boost::get<double>(v);//抛出异常
}
catch (std::exception& e)
{
TRACE("%s",e.what());
}
2.boost::apply_visitor
std::vector<boost::any> vcData;
struct output : public boost::static_visitor<>
{
void operator()(double &d) const
{
vcData.push_back(d);
}
void operator()(char &c) const
{
vcData.push_back(c);
}
void operator()(std::string &s) const
{
vcData.push_back(s);
}
};
void CMFC08Dlg::OnBnClickedButton2()
{
boost::variant<double, char, std::string> v;
v = 3.14;
boost::apply_visitor(output(), v);
v = 'A';
boost::apply_visitor(output(), v);
v = "Hello, world!";
boost::apply_visitor(output(), v);
}
/*
template <typename Visitor, typename Visitable>
inline
BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(typename Visitor::result_type) //这里是返回一个 Visitor::result_type
apply_visitor(const Visitor& visitor, Visitable& visitable)
{
return visitable.apply_visitor(visitor);
}
上面是apply_visitor的函数定义,传递的两个参数都是一个模板的参数,
Visitor& visitor(访问者类)
Visitable& visitable(支持访问者的类)
所以从上面看出
我们调用 apply_visitor,满足如下条件即可:
1.Visitor& visitor(访问者类),定义了 Visitor::result_type 即可
1.static_visitor 源码
namespace detail {
struct is_static_visitor_tag { };
typedef void static_visitor_default_return;//1.重新定义了 void 指向为 static_visitor_default_return
} // namespace detail
template <typename R = ::boost::detail::static_visitor_default_return> //2.默认的类型是void,所以直接static_visitor<>表示用void类型
class static_visitor
: public detail::is_static_visitor_tag
{
public: // typedefs
typedef R result_type;//3.将传递进来的类型定义为 result_type
protected: // for use as base class only
#if !defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) && !defined(BOOST_NO_CXX11_NON_PUBLIC_DEFAULTED_FUNCTIONS)
static_visitor() = default;
~static_visitor() = default;
#else
static_visitor() BOOST_NOEXCEPT { }
~static_visitor() BOOST_NOEXCEPT { }
#endif
};
2.Visitable& visitable(支持访问者的类),实现成员函数apply_visitor即可
*/
struct output //: public boost::static_visitor<>
{
typedef void result_type;//所以实现方法二
void operator()(double &d) const
{
vcData.push_back(d);
}
void operator()(char &c) const
{
vcData.push_back(c);
}
void operator()(std::string &s) const
{
vcData.push_back(s);
}
};