boost 笔记点滴:optional 和 variant

来源:互联网 发布:流程图用什么软件画 编辑:程序博客网 时间:2024/06/03 18:55

只是一点例子,没有什么解释;主要是给自己看,作为一个笔记而已。

boost::optional例子:

#include <boost/optional.hpp>#include <iostream>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("<<inner.v<<")";      return out;    }    int get_v()    {      return v;    }    void set_v(int _v)    {      v = _v;    }};int main(){  boost::optional<Inner> option1;  assert(!option1);  boost::optional<Inner> option2(boost::none);  assert(!option2);  Inner inner3(3);  //the following two statements are equal to each other;  boost::optional<Inner> option3(inner3);  // output: Inner(const Inner& other)  -- copy the object;  boost::optional<Inner> 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<Inner> 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<Inner> 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 <vector>#include <algorithm>  //std::for_each#include <iostream>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("<<inner.v<<")";      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<Inner>(&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::get<std::string>(&v);  assert(p1==NULL);  assert(p2==NULL);  //1.2 get a reference of the object held inside;  Inner& ref_inner = boost::get<Inner>(v);  ref_inner.set_v(ref_inner.get_v()*2);  std::cout << "v = " << v << std::endl; //output: v = Inner(400)  //int& ref1 = boost::get<int>(v);                 //boost::bad_get: failed value get using boost::get;  //std::string& ref2 = boost::get<std::string>(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<Inner>(&v);  std::string* p4 = boost::get<std::string>(&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<Inner>(v);             //boost::bad_get: failed value get using boost::get;  //std::string& ref4 = boost::get<std::string>(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::get<std::string>(&v);  *ptr_str += *ptr_str;  std::cout << "v = " << v << std::endl; //output: v = hellohello  Inner* p5 = boost::get<Inner>(&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::get<std::string>(v);  ref_str += ref_str;  std::cout << "v = " << v << std::endl; //output: v = hellohellohellohello  //Inner& ref5 = boost::get<Inner>(v);   //boost::bad_get: failed value get using boost::get;  //int& ref6 = boost::get<int>(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::vector<boost::variant<int, 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::vector<boost::variant<int, Inner, std::string> >::iterator itr=vect.begin(); itr!=vect.end(); ++itr)    std::cout<<*itr<<std::endl;  //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::vector<boost::variant<int, Inner, std::string> >::iterator itr=vect.begin(); itr!=vect.end(); ++itr)    std::cout<<*itr<<std::endl;  ///////////////////////////// 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<Inner, int, std::string> v2;  return 0;}
原创粉丝点击