【问题标题】:boost::bind member function as argument inside its own member functionboost::bind 成员函数作为其自身成员函数中的参数
【发布时间】:2021-07-10 17:29:08
【问题描述】:

我正在关注 boost asio 的教程 (https://www.gamedev.net/blogs/entry/2249317-a-guide-to-getting-started-with-boostasio/)。

现在我想将本教程的某些方面转换为一个类,以进一步了解代码的每个部分中实际发生的情况。所以我试图加强绑定:

class LDserver
{
public:
    void workerThread(boost::shared_ptr<boost::asio::io_service> io_service)   
        {
            io_service->run();    
        } 
    void createThreads()
        {
            this->worker_threads.create_thread(boost::bind(&LDserver::workerThread, this->io_service));
        }
    
        ~LDserver() = default;
        boost::thread_group worker_threads;
        boost::shared_ptr<boost::asio::io_service> io_service = boost::make_shared<boost::asio::io_service>();
        boost::shared_ptr<boost::asio::io_service::work> work = boost::make_shared<boost::asio::io_service::work>(*this->io_service);
        boost::asio::io_service::strand strand = boost::asio::io_service::strand(*this->io_service);
};

在文档之后,它指出这应该是正确的语法 AS 它自己,所以不作为参数。但相反,我收到来自 boost::bind 库的错误消息。

Severity    Code    Description Project File    Line    Suppression State
Error   C2440   'return': cannot convert from 'R (__cdecl &)' to 'R'    LockManager C:\Boost\boost_1_75_0\boost_1_75_0\boost\bind\bind.hpp  227 

如果我按照文档将它放在主循环中,它可以正常工作,它甚至可以将成员变量作为参数:

LDserver s1;
for (int i = 0; i <= 2; i++)
    {
        s1.worker_threads.create_thread(boost::bind(&workerThread, s1.io_service));
    }

通过注释掉我 100% 确定,因为它没有采用我将 worketThread() 成员函数语法化为正确的方式,但是在花了 2 天的时间尝试并找到答案之后,我希望这里有人能启发我.

【问题讨论】:

  • 请通过提供minimal reproducible example 完成您得到的确切错误来使您的问题独立。
  • 已编辑,现在正确吗?
  • 我现在可以在添加几个标题后得到 an 错误。我不确定这是否是等效错误,但现在可以玩了。

标签: c++ boost boost-asio boost-thread boost-bind


【解决方案1】:

问题在于线程函数不是静态的,因此它需要this (LDServer*) 的参数。或者你也可以static:

  static void workerThread(boost::shared_ptr<ba::io_service> io_service) {
      io_service->run();
  }
  void createThreads() {
      worker_threads.create_thread(
          boost::bind(&LDserver::workerThread, io_service));
  }

然而,所有猖獗的动态分配、共享所有权和手动线程,以及 boost bind/shared_ptr 而不是标准库都是代码异味。如果您正在使用 VeryOldOrBadBook(TM) 来学习这一点,请比较:

#include <boost/asio.hpp>
namespace net = boost::asio;

class LDserver : public std::enable_shared_from_this<LDserver> {
    using executor_type = net::thread_pool::executor_type;

    net::thread_pool           _ctx{1}; // one thread please
    net::strand<executor_type> _strand{_ctx.get_executor()};

  public:
    ~LDserver() {
        _ctx.join(); // don't forget to join your threads anyway
    }
};

【讨论】:

  • 这是非常好的内容!刚刚开始接触 C++ 中的网络,这是我能找到的关于 boost::asio 的唯一优秀而全面的教程。所以这就是为什么它可能闻起来很香;)但是你的附加信息很有意义!将继续以此为基础。赞赏!
  • 我实际上还有另一个问题,我希望这仍然能传达给您...如果我需要动态创建线程怎么办?你将如何在你的例子中实现它?一个相当模糊的问题,但我很难找到涵盖 asio 基础知识的好的源材料。有的话可以分享一下吗?
  • “动态创建线程”有点反模式,但你当然可以。如果你有一些你被卡住的代码,请考虑发布一个单独的问题。
猜你喜欢
  • 1970-01-01
  • 2013-11-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-01
  • 1970-01-01
  • 2017-06-10
  • 1970-01-01
相关资源
最近更新 更多