簡體   English   中英

為什么std :: bind和boost :: bind不能在這個Boost.Asio教程中互換使用

[英]Why can't std::bind and boost::bind be used interchangeably in this Boost.Asio tutorials

我在Boost.Asio文檔中嘗試了不同的教程,並試圖用C ++ 11替換boost組件。 但是,我在Timer.5中使用std :: bind時出錯了 - 在多線程程序中同步處理程序 這是建議的代碼:

#include <iostream>
#include <boost/asio.hpp>
#include <boost/thread/thread.hpp>
#include <boost/bind.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>

class printer { /* Not relevent here */ };

int main()
{
  boost::asio::io_service io;
  printer p(io);
  boost::thread t(boost::bind(&boost::asio::io_service::run, &io));
  io.run();
  t.join();

  return 0;
}

我試圖取代boost::thread通過std::threadboost::bind通過std::bind 這是我的代碼:

#include <functional>
#include <iostream>
#include <thread>
#include <boost/asio.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>

class printer { /* Not relevent here */ };

int main() {
    boost::asio::io_service io;
    printer p(io);
    std::thread t(std::bind(&boost::asio::io_service::run, &io));
    io.run();
    t.join();
}

在使用GCC 4.7進行編譯時,我得到了這個編譯時錯誤:

g++ -std=c++0x main.cpp -lboost_system -lboost_date_time -lpthread
main.cpp: In function ‘int main()’:
main.cpp:52:60: erreur: no matching function for call to ‘bind(<unresolved overloaded function type>, boost::asio::io_service*)’
main.cpp:52:60: note: candidates are:
/usr/include/c++/4.6/functional:1444:5: note: template<class _Functor, class ... _ArgTypes> typename std::_Bind_helper::type std::bind(_Functor&&, _ArgTypes&& ...)
/usr/include/c++/4.6/functional:1471:5: note: template<class _Result, class _Functor, class ... _ArgTypes> typename std::_Bindres_helper::type std::bind(_Functor&&, _ArgTypes&& ...)

這個錯誤來自何處,考慮到我沒有使用任何boost::asio::placeholders (在此stackoverflow問題中解釋應該std :: bind是否與boost :: asio兼容? )?

boost::asio::io_service::run()成員函數被重載:一個版本不帶參數,而另一個版本帶一個參數。 也就是說,獲取boost::asio::io_service::run需要一個上下文,在該上下文中編譯器可以直接推導出函數的簽名。 但是, std::bind()不需要做演繹魔法,而似乎boost::bind()試圖找到匹配的重載,即它的第一個參數類型似乎很容易被約束(假設確實是增強示例)編譯)。

解決這個問題你可以明確指定std::bind()的第一個參數的類型(它也應該與boost::bind() ),例如:

std::bind(static_cast<size_t (boost::asio::io_service::*)()>(&boost::asio::io_service::run), &io);

我沒有檢查標准是否有任何要求,但如果它確實沒有做任何要求,我會考慮一個實現,雖然它的工作量較少,但是並沒有用英雄來推斷出論證類型的質量更好:它需要用戶編寫的代碼可以在另一個編譯器上編譯。

簡單來說,在C ++ 11之后,你可以使用lambdas來避免所有的faff並大大簡化整個事情。 老人:

boost::thread t(boost::bind(&boost::asio::io_service::run, &io));

或者std :: version:

std::thread t(boost::bind(static_cast<size_t (boost::asio::io_service::*)()>(&boost::asio::io_service::run), &io_service));

變得公正:

std::thread t([&io_service](){io_service.run();});

這是一個巨大的PITA,所以謝謝Dietmar的暗示。 對於那些使用boost :: bind的人來說,你的解決方案看起來像這樣:

// create the io_service    

boost::asio::io_service io_service;

 // assign some work to asio before starting
 {
    io_service.post(&some_work);   // just for example
    ....
 }

boost::thread t(boost::bind(static_cast<size_t (boost::asio::io_service::*)()>(&boost::asio::io_service::run), &io_service));

// work should be executed in a new thread

t.join()

return;

由於您已經在使用C ++ 11:lambdas可能是std :: bind的替代品,例如,std :: thread t(&io {io.run();});. 這完全避免了重載決策。

要獲得正確的輸出,解決方案(在asio standalone或boost :: asio中)是:

asio::io_service io;
auto ptrToIoService = &io;
printer p(io);

//asio::thread t(std::bind(&asio::io_service::run, &io));
//asio::thread t([&io]() {io.run();});
asio::thread t([ptrToIoService] () { ptrToIoService->run();});

請參閱“項目31避免默認捕獲模式”下的“有效的現代C ++”。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM