只是一点例子,没有什么解释;主要是给自己看,作为一个笔记而已。
boost::optional例子:
#include
#include
class Inner
{
private:
int v;
public:
Inner(int _v) : v(_v)
{}
Inner(const Inner& other) : v(other.v)
{
std::cout << "Inner(const Inner& other)" << std::endl;
}
Inner& operator=(const Inner& other)
{
this->v = other.v;
std::cout << "Inner& operator=(const Inner& other)" << std::endl;
return *this;
}
bool operator==(const Inner& other)
{
std::cout << "bool operator==(const Inner& other)" << std::endl;
return this->v == other.v;
}
friend std::ostream& operator<<(std::ostream& out, const Inner& inner)
{
out<<"Inner("<")";
return out;
}
int get_v()
{
return v;
}
void set_v(int _v)
{
v = _v;
}
};
int main()
{
boost::optional option1;
assert(!option1);
boost::optional option2(boost::none);
assert(!option2);
Inner inner3(3);
//the following two statements are equal to each other;
boost::optional option3(inner3); // output: Inner(const Inner& other) -- copy the object;
boost::optional option4 = inner3; // output: Inner(const Inner& other) -- copy the object;
assert(*option3 == *option4); // output: bool operator==(const Inner& other) -- behaves like a pointer;
//optional behaves like a pointer, but it holds a copy of the object instead of the pointer of the object;
std::cout << "option3 = " << option3->get_v() << std::endl; // output: option3 = 3
option3->set_v(8);
std::cout << "option3 = " << option3->get_v() << std::endl; // output: option3 = 8
std::cout << "inner3 = " << inner3.get_v() << std::endl; // output: inner3 = 3
boost::optional option5;
option5 = option4; // output: Inner(const Inner& other) -- make a copy (copy constructor)
std::cout << "option4 = " << option4->get_v() << std::endl; // output: option4 = 3
std::cout << "option5 = " << option5->get_v() << std::endl; // output: option5 = 3
option5->set_v(5);
std::cout << "option4 = " << option4->get_v() << std::endl; // output: option4 = 3
std::cout << "option5 = " << option5->get_v() << std::endl; // output: option5 = 5
boost::optional option6(inner3);
std::cout << "option6 = " << option6->get_v() << std::endl; // output: option6 = 3
option6 = option5; // output: Inner& operator=(const Inner& other) -- make a copy (operator=)
std::cout << "option6 = " << option6->get_v() << std::endl; // output: option6 = 5
return 0;
}
boost::variant例子:
#include "boost/variant.hpp"
#include
#include //std::for_each
#include
class Inner
{
private:
int v;
public:
Inner(int _v) : v(_v)
{}
Inner(const Inner& other) : v(other.v)
{
std::cout << "Inner(const Inner& other)" << std::endl;
}
Inner& operator=(const Inner& other)
{
this->v = other.v;
std::cout << "Inner& operator=(const Inner& other)" << std::endl;
return *this;
}
bool operator==(const Inner& other)
{
std::cout << "bool operator==(const Inner& other)" << std::endl;
return this->v == other.v;
}
friend std::ostream& operator<<(std::ostream& out, const Inner& inner)
{
out<<"Inner("<")";
return out;
}
int get_v()
{
return v;
}
void set_v(int _v)
{
v = _v;
}
};
class multiply_two_visitor : public boost::static_visitor<>
{
public:
void operator()(int& i) const
{
i *= 2;
}
void operator()(Inner& inner) const
{
inner.set_v(inner.get_v()*2);
}
void operator()(std::string& str) const
{
str += str;
}
};
int main()
{
// the semantics is like:
// union
// {
// int i;
// Inner inner;
// std::string s;
// } v;
boost::variant<int, Inner, std::string> v;
//////////////////////// 1. hold an object of Inner class ////////////////////////
Inner inner(100);
v = inner; // output:
// Inner(const Inner& other)
// Inner(const Inner& other)
// copy to argument, then copy to the inside held object;
std::cout << "v = " << v << std::endl; //output: v = Inner(100)
//1.1 get a pointer of the object held inside;
Inner* ptr_inner = boost::get(&v);
ptr_inner->set_v(ptr_inner->get_v()*2);
std::cout << "v = " << v << std::endl; //output: v = Inner(200)
int* p1 = boost::get<int>(&v);
std::string* p2 = boost::getstring>(&v);
assert(p1==NULL);
assert(p2==NULL);
//1.2 get a reference of the object held inside;
Inner& ref_inner = boost::get(v);
ref_inner.set_v(ref_inner.get_v()*2);
std::cout << "v = " << v << std::endl; //output: v = Inner(400)
//int& ref1 = boost::get(v); //boost::bad_get: failed value get using boost::get;
//std::string& ref2 = boost::get(v); //boost::bad_get: failed value get using boost::get;
//1.3 apply visitor
//this won't compile without any one of the 3 member functions of multiply_two_visitor;
boost::apply_visitor(multiply_two_visitor(), v);
std::cout << "v = " << v << std::endl; //output: v = Inner(800)
///////////////////////////////// 2. hold an int /////////////////////////////////
v = 8;
std::cout << "v = " << v << std::endl; //output: v = 8
//2.1 get a pointer of the object held inside;
int* ptr_int = boost::get<int>(&v);
*ptr_int *= 2;
std::cout << "v = " << v << std::endl; //output: v = 16
Inner* p3 = boost::get(&v);
std::string* p4 = boost::getstring>(&v);
assert(p3==NULL);
assert(p4==NULL);
//2.2 get a reference of the object held inside;
int& ref_int = boost::get<int>(v);
ref_int *= 2;
std::cout << "v = " << v << std::endl; //output: v = 32
//Inner& ref3 = boost::get(v); //boost::bad_get: failed value get using boost::get;
//std::string& ref4 = boost::get(v); //boost::bad_get: failed value get using boost::get;
//2.3 apply visitor
//this won't compile without any one of the 3 member functions of multiply_two_visitor;
boost::apply_visitor(multiply_two_visitor(), v);
std::cout << "v = " << v << std::endl; //output: v = 64
////////////////////////////// 3. hold a std::string //////////////////////////////
v = std::string("hello");
std::cout << "v = " << v << std::endl; //output: v = hello
//3.1 get a pointer of the object held inside;
std::string* ptr_str = boost::getstring>(&v);
*ptr_str += *ptr_str;
std::cout << "v = " << v << std::endl; //output: v = hellohello
Inner* p5 = boost::get(&v);
int* p6 = boost::get<int>(&v);
assert(p5==NULL);
assert(p6==NULL);
//3.2 get a reference of the object held inside;
std::string& ref_str = boost::getstring>(v);
ref_str += ref_str;
std::cout << "v = " << v << std::endl; //output: v = hellohellohellohello
//Inner& ref5 = boost::get(v); //boost::bad_get: failed value get using boost::get;
//int& ref6 = boost::get(v); //boost::bad_get: failed value get using boost::get;
//3.3 apply visitor
//this won't compile without any one of the 3 member functions of multiply_two_visitor;
boost::apply_visitor(multiply_two_visitor(), v);
std::cout << "v = " << v << std::endl; //output: v = hellohellohellohellohellohellohellohello
////////////////////////////// 4. delayed visitation //////////////////////////////
std::vectorint, Inner, std::string> > vect;
vect.push_back(Inner(80));
vect.push_back(81);
vect.push_back(std::string("world"));
//output:
// Inner(80)
// 81
// world
for(std::vectorint, Inner, std::string> >::iterator itr=vect.begin(); itr!=vect.end(); ++itr)
std::cout<<*itr<//boost::apply_visitor(visitor): does not immediately apply the given visitor to any variant, but rather
//returns a function object that can be called later.
multiply_two_visitor visitor;
std::for_each(vect.begin(), vect.end(), boost::apply_visitor(visitor));
//output:
// Inner(160)
// 162
// worldworld
for(std::vectorint, Inner, std::string> >::iterator itr=vect.begin(); itr!=vect.end(); ++itr)
std::cout<<*itr<///////////////////////////// 5. copy between variants ////////////////////////////
v = inner; // output: Inner(const Inner& other)
// Inner(const Inner& other)
// copy to argument, then copy to the inside held object;
boost::variant<int, Inner, std::string> v1;
v1 = v; // output: Inner(const Inner& other) -- make a copy (copy constructor)
std::cout << "v = " << v << std::endl; //output: v = Inner(100)
std::cout << "v1 = " << v1 << std::endl; //output: v1 = Inner(100)
boost::apply_visitor(multiply_two_visitor(), v1);
std::cout << "v = " << v << std::endl; //output: v = Inner(100)
std::cout << "v1 = " << v1 << std::endl; //output: v1 = Inner(200)
v1 = v; // output: Inner& operator=(const Inner& other) -- make a copy (operator=)
std::cout << "v = " << v << std::endl; //output: v = Inner(100)
std::cout << "v1 = " << v1 << std::endl; //output: v1 = Inner(100)
////////////////////////// 6. default value of variant ///////////////////////////
// this doesn't compile, because default variant will hold a default value of the 1st type;
// the 1st type Inner, but it doesn't have the default constructor Inner::Inner();
// To make it compile, just add the default constructor Inner::Inner();
//boost::variant v2;
return 0;
}