首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用C++11信号替换boost-signals2

用C++11信号替换boost-signals2
EN

Stack Overflow用户
提问于 2019-06-04 21:08:44
回答 2查看 2.1K关注 0票数 3

我是一名研究程序员,正在为无人驾驶车辆开发自动驾驶系统,我正在修改另一个项目的一些开源代码,以使其成为车辆控制的驾驶员。其思想是拥有一个模块,该模块通常处理加载特定于车辆的驱动程序作为库的控制,现有实现使用boost::signals2将模块函数调用绑定到驱动程序。因为这是它目前唯一使用boost的东西,所以我想删除boost依赖并使用C++信号,但我很难弄清楚如何做到这一点。

我一直在努力阅读boost::signals2和C++信号的一般知识,看看我是否可以自学原理和语法:- https://en.cppreference.com/w/cpp/utility/program/signal - https://testbit.eu/2013/cpp11-signal-system-performance - https://simmesimme.github.io/tutorials/2015/09/20/signal-slot我认为我正在理解这些概念,但它的实现让我感到困惑。我发布的第一个和第二个资源使它看起来像是C++11内置的C++信号,但是第三个链接中的教程似乎定义了它自己的信号类,并且似乎根本没有使用第一个中的语法。

看起来其他项目以前也这样做过(https://github.com/cinder/Cinder/issues/619),但我还没有找到任何具体的例子来展示前后的比较--对我来说,查看实现通常是点击理论的正确之处。

从驱动程序库头文件:

代码语言:javascript
复制
class InterfaceBase
{
   InterfaceBase( const Config& cfg );
   virtual ~InterfaceBase() { }

   boost::signals2::signal<void (const InterfaceState& state)> signal_state_change;
}

在驱动程序cpp文件中:

代码语言:javascript
复制
void InterfaceBase::check_change_state()
{
   if( state_ != previous_state )
   {
      signal_state_change( state_ );
   }
}

在模块cpp中:

代码语言:javascript
复制
template<typename Signal, typename Slot>
   void connect( Signal* signal, Slot slot )
{ signal->connect( slot ); }

template<typename Signal, typename Obj, typename A1>
   void connect( Signal* signal, Obj* obj, void( Obj::*mem_func )( A1 ))
{ connect( signal, boost::bind( mem_func, obj, _1 )); }

Interface::Interface()
{
   if( cfg_.has_driver_lib_path() )
   {
      driver_library_handle = dlopen( cfg_.driver_lib_path().c_str(), RTLD_LAZY );
      if( !driver_library_handle )
      {
         exit( EXIT FAILURE );
      }
   }
   else
   {
      exit( EXIT_FAILURE );
   }
   driver_ = load_driver( &cfg_ );

   connect( &driver_->signal_state_change, this, &Interface::ProcessStateChange );
}

驱动程序声明一个信号,它可以使用该信号将数据发送到加载它的模块,然后该模块将该信号绑定到一个函数,以便当该信号被调用并向其提供数据时,数据将转到该函数。我只是想弄清楚如何在不使用Boost的情况下完成同样的事情,我猜这意味着我也想知道如何替换boost::bind。任何指向正确方向的人都非常感激;我将继续努力,如果我发现了其他问题,我会发表文章,以防对将来走上同样道路的任何人有所帮助。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-06-04 21:23:02

这里的问题是,有两种相关但不同的技术,都是命名信号。

<signal.h>和相应的<csignal>中的信号构造是signals in the POSIX sense的,并且与错误处理相关,例如当OS终止程序或发生灾难性的内部错误时。

诸如Boost.signals2、Qt的信号/槽等Signals and slots是观察者模式的更一般的实现,它允许一段代码为另一段代码提供一种松散耦合的方式,以便在某个事件发生时获得通知或回调。

前者实际上是后者的一个子集,因为POSIX信号主要与错误和终止事件有关,而信号和时隙通常也适用于不太危险的事件,如“网络数据包已到达!”或者“用户点击了一个按钮!”

我不建议将一个通用的信号槽解决方案硬塞到过时的(和C风格的) POSIX信号API中。

虽然没有标准的C++信号/槽库,但有各种第三方库,如您的一些链接所示。除非你有一个令人信服的理由重新发明轮子,否则我不建议你自己滚动。(如果您必须使用自己的代码,那么std::function是一个显而易见的起点。)Boost的是一个高质量的实现,既然你已经在使用它了,我会坚持使用它。(我们公司的经验法则是,在所有条件大致相同的情况下,"std > Boost > Qt > other",但YMMV。)

如果你只是想减少Boost文件夹的占用空间,Boost提供的BCP就可以做到这一点。

票数 9
EN

Stack Overflow用户

发布于 2021-10-22 09:28:18

现在C++标准已经取得了这样的进步,我比以往任何时候都更不愿意使用Boost头。在浏览github时,我遇到了这个提升Signals2的替代方案:

https://github.com/cpp11nullptr/lsignal

尽管它的文档可以改进(不是在自述文件中使用的完整示例),但它似乎简单有效。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56444592

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档