从boost转为c++11

从boost转为c++11

随着boost的特性进入c++11,目前来看项目用到的boost库除了asio之外其他都可以转而使用std标准库。

boost:bind :可以替换为std::bind, 但是最好不要再使用bind,而是使用lambda表达式。

智能指针:boost::shared_ptr替换为std::shared_ptr;

                  boost::scoped_ptr替换为std::unique_ptr;

                  boost::enable_shared_from_this替换为std::enable_shared_from_this;

原子操作:  boost::atomic替换为std::atomic;

互斥锁:boost::scoped_lock替换为std::unique_lock<std::mutex>,

               boost::condition_variable替换为std::condition_variable;

线程:boost::thread替换为std::thread;

目前看来还无法用c++11替换boost的库有:

boost::locale

boost::posix_time

boost::algorithm::string

boost::lexcal_cast

boost::file_system

boost::property_tree

boost::assert

其中碰到的一些问题:

1.  关于为什么用lambda替换bind 一个很好的stackoverflow回答

https://stackoverflow.com/questions/17363003/why-use-stdbind-over-lambdas-in-c14/17545183

使用std::bind代替boost::bind时出现编译错误:

https://stackoverflow.com/questions/8924149/should-stdbind-be-compatible-with-boostasio

https://stackoverflow.com/questions/9048119/why-cant-stdbind-and-boostbind-be-used-interchangeably-in-this-boost-asio-t

2. boost asio库作者也在asio的example里提供了一些如何使用lambda与asio结合的例子

如:https://www.boost.org/doc/libs/1_67_0/doc/html/boost_asio/example/cpp11/http/server/connection.cpp 使用[this, self]的lambda表达式。

3. boost::asio的async_connect的回调函数用lambda

https://stackoverflow.com/questions/42132104/how-to-call-boost-async-connect-as-member-function-using-lamba-as-connect-handle

4. 类的成员函数中bind时为什么有时候有shared_from_this(), 有时候用this?

https://stackoverflow.com/questions/47459959/use-case-of-shared-from-this-and-this

5. bind有一个奇特的现象(but this is by design): bind返回的函数对象的参数个数是n,但调用该函数对象时可以提供大于n个参数,多余的参数在实际调用时会被自动忽略。

如下例子中,boost::asio::async_wirte()的第三个参数根据手册规定必须是有两个参数的函数, 而std::bind(&TCPReceiver::HandleWrite, shared_from_this(), std::placeholders::_1)) 返回的是只有一个参数的函数,但是下面的例子可以顺利的编译运行。

void TCPReceiver::HandleWrite(const boost::system::error_code& e) {
  writing_ = false;
  if (e) {
    VSS_LOG(logger_, ILogger::LOG_INFO) << "HandleWrite error: "
      << e.message();
    DoHandleError(e);
  }
}

void TCPReceiver::DoAsyncWrite() {
  // start to write
  const uint8_t* content = NULL;
  int data_size = 0;
  serializer_->Flush(&content, &data_size);
  if (data_size > 0) {
    boost::asio::async_write (
      *socket_,
      boost::asio::buffer(content, data_size),
      std::bind(&TCPReceiver::HandleWrite, shared_from_this(), std::placeholders::_1));
    writing_ = true;
    last_sent_time_ = boost::posix_time::second_clock::local_time();
  }
}

但是使用lambda替代bind时,就需要在lambda中明确写出来第二个参数。如下:

void TCPReceiver::HandleWrite(const boost::system::error_code& e) {
  writing_ = false;
  if (e) {
    VSS_LOG(logger_, ILogger::LOG_INFO) << "HandleWrite error: "
      << e.message();
    DoHandleError(e);
  }
}

void TCPReceiver::DoAsyncWrite() {
  // start to write
  auto self(shared_from_this());
  const uint8_t* content = NULL;
  int data_size = 0;
  serializer_->Flush(&content, &data_size);
  if (data_size > 0) {
    boost::asio::async_write (
      *socket_,
      boost::asio::buffer(content, data_size),
      std::bind(&TCPReceiver::HandleWrite, shared_from_this(), std::placeholders::_1));
      [this, self](const boost::system::error_code& ec, std::size_t bytes_transferred)
      {
         HandleWrite(ec);
      }
    );
    writing_ = true;
    last_sent_time_ = boost::posix_time::second_clock::local_time();
  }
}

参考stackoverflow的回答:https://stackoverflow.com/questions/22676281/boostbind-binds-extra-arguments

发布了87 篇原创文章 · 获赞 64 · 访问量 25万+

猜你喜欢

转载自blog.csdn.net/wqfhenanxc/article/details/87337104
今日推荐