标签: boost-signals2

如何以及为何使用Boost信号2?

学习c ++并尝试熟悉一些模式.该signals2 DOC显然有事情,我可以插槽和信号做繁多.我不明白的是我应该使用哪种类型的应用程序(用例).

我正在考虑调度变更事件的状态机.来自动态类型的背景(C#,Java等),您将使用事件调度程序或静态引用或回调.

使用跨类回调在c ++中是否存在困难?这就是为什么信号2存在的原因

示例案例之一是文档/视图.这种模式如何比使用函数向量并在循环中调用每个函数更好地适用,或者说在注册的侦听类实例中调用状态更改的lambda?

class Document
{
public:
    typedef boost::signals2::signal<void ()>  signal_t;

public:
    Document()
    {}

    /* Connect a slot to the signal which will be emitted whenever
      text is appended to the document. */
    boost::signals2::connection connect(const signal_t::slot_type &subscriber)
    {
        return m_sig.connect(subscriber);
    }

    void append(const char* s)
    {
        m_text += s;
        m_sig();
    }

    const std::string& getText() const
    {
        return m_text;
    }

private:
    signal_t    m_sig;
    std::string m_text;
};
Run Code Online (Sandbox Code Playgroud)

class TextView
{
public: …
Run Code Online (Sandbox Code Playgroud)

c++ events boost boost-signals2

20
推荐指数
1
解决办法
2万
查看次数

强制删除boost :: signals2中的插槽

我发现boost :: signals2使用了一些连接槽的延迟删除,这使得很难将连接用作管理对象生命周期的东西.我正在寻找一种方法来强制插槽在断开连接时直接删除.如何通过不同的方式设计我的代码来解决问题的任何想法也很感激!

这是我的场景:我有一个Command类负责执行异步需要时间的事情,看起来像这样(简化):

class ActualWorker {
public:
    boost::signals2<void ()> OnWorkComplete;
};

class Command : boost::enable_shared_from_this<Command> {
public:
    ...

    void Execute() {
        m_WorkerConnection = m_MyWorker.OnWorkDone.connect(boost::bind(&Command::Handle_OnWorkComplete, shared_from_this());

        // launch asynchronous work here and return
    }

    boost::signals2<void ()> OnComplete;

private:
    void Handle_OnWorkComplete() {
        // get a shared_ptr to ourselves to make sure that we live through
        // this function but don't keep ourselves alive if an exception occurs.
        shared_ptr<Command> me = shared_from_this();

        // Disconnect from the signal, ideally deleting the slot object …
Run Code Online (Sandbox Code Playgroud)

c++ boost boost-signals2

12
推荐指数
1
解决办法
3910
查看次数

Visual Studio 2012 C++使用Boost Signal2编译错误

我正在使用带有以下Boost Signals2代码的Visual Studio 2012 Ultimate:https://github.com/cfobel/boost_signals2/blob/master/hello_world_0.cpp 它会生成以下错误:

c:\program files (x86)\microsoft visual studio 11.0\vc\include\xmemory(348): error C4996: 'std::_Uninitialized_copy0': Function call with parameters that may be unsafe - this call relies on the caller to check that the passed values are correct. To disable this warning, use -D_SCL_SECURE_NO_WARNINGS. See documentation on how to use Visual C++ 'Checked Iterators'
1>          c:\program files (x86)\microsoft visual studio 11.0\vc\include\xmemory(333) : see declaration of 'std::_Uninitialized_copy0'
1>          c:\libraries\boost_1_52_0\boost\signals2\detail\auto_buffer.hpp(192) : see reference to function template instantiation '_FwdIt std::uninitialized_copy<I,boost::variant<T0_,T1>*>(_InIt,_InIt,_FwdIt)' …
Run Code Online (Sandbox Code Playgroud)

c++ boost visual-studio boost-signals2

10
推荐指数
1
解决办法
4056
查看次数

信号和线程 - 设计决策的好坏?

我必须编写一个执行高度计算密集型计算的程序.该程序可能会运行几天.可以在不同的线程中轻松分离计算,而无需共享数据.我想要一个GUI或一个Web服务,告诉我当前的状态.

我目前的设计使用BOOST :: signals2和BOOST :: thread.它编译并到目前为止按预期工作.如果一个线程完成一次迭代并且有新数据可用,则它会调用一个连接到GUI类中的插槽的信号.

我的问题:

  • 这种信号和线程的组合是一个明智的想法吗?我是另一个论坛,有人建议别人不要"走这条路".
  • 附近是否有潜在的致命陷阱,我没有看到?
  • 我期望的现实,这将是"容易"用我的GUI类来提供Web界面或QT,一个VTK或任何窗口?
  • 有没有更聪明的选择(像其他升压库),我忽略了?

以下代码编译

g++ -Wall -o main -lboost_thread-mt <filename>.cpp
Run Code Online (Sandbox Code Playgroud)

代码如下:

#include <boost/signals2.hpp>
#include <boost/thread.hpp>
#include <boost/bind.hpp>

#include <iostream>
#include <iterator>
#include <string>

using std::cout;
using std::cerr;
using std::string;

/**
 * Called when a CalcThread finished a new bunch of data.
 */
boost::signals2::signal<void(string)> signal_new_data;

/**
 * The whole data will be stored here.
 */
class DataCollector
{
    typedef boost::mutex::scoped_lock scoped_lock;
    boost::mutex mutex;

public:
    /**
     * Called by CalcThreads call the …
Run Code Online (Sandbox Code Playgroud)

c++ boost-thread boost-signals2

6
推荐指数
2
解决办法
5477
查看次数

如何实现`boost :: signals2`中的信号签名?

我已经boost::signals2在我的项目中使用了一段时间.令我感到羞耻的是,我仍然不明白它们是如何在引擎盖下实现.我的问题已经从信号的定义开始了.如何定义如

boost::signals2::signal< void (bool, double) > 
Run Code Online (Sandbox Code Playgroud)

如何处理?我可以从实现细节中看到签名成为一个适当命名的模板参数Signature.但是,我不懂语法.C++标准是否允许这种语法?如果以这种形式提供功能签名,信号如何"存储"?

我已经尝试查看源代码,但无法找到此语法的解释.任何帮助,将不胜感激.

c++ implementation templates boost boost-signals2

6
推荐指数
1
解决办法
414
查看次数

clang不喜欢boost :: signals2?

我整天都在使用Boost :: Signals2库从代码部分中获取编译器错误.我已经将我想要做的事情简化为一个最小的例子:

#include <boost/signals2.hpp>

int foo();

struct first_nonzero
{
    using result_type = int;

    template <typename It>
    result_type operator()(It first, It last) const
    {
    while(first != last)
    {
        if(*first != 0)
        {
            return *first;
        }
    }
    return 0;
    }
};

int foo()
{
    using signal = boost::signals2::signal<int (), first_nonzero>;
    signal s;
    return s();
}
Run Code Online (Sandbox Code Playgroud)

当我尝试编译此代码段时

clang -o foo.o -c foo.cpp -std=c++11 -Weverything -Wno-c++98-compat
Run Code Online (Sandbox Code Playgroud)

我得到一个模板推导错误,似乎来自信号库本身:

In file included from foo.cpp:1:
In file included from /usr/include/boost/signals2.hpp:19:
In file included from /usr/include/boost/signals2/signal.hpp:38:
In …
Run Code Online (Sandbox Code Playgroud)

c++ boost clang boost-signals2 c++11

6
推荐指数
1
解决办法
480
查看次数

是否存在序列化boost :: signals2信号调用的现有方法?

我想序列化boost :: signals2信号的多线程调用,以确保来自对象的状态变化的通知以明确定义的顺序到达插槽.

背景

我有一个在多线程程序中具有内部状态的对象.内部状态的某些部分对程序的其他部分很有意义,并且对象通过使用boost :: signals2信号来暴露状态更改,类似于:

class ObjectWithState {
public:
    enum State {
        STATE_A,
        STATE_B,
        STATE_C,
    };

    void OnEvent() {
        State newState;
        {
            boost::lock_guard<boost::mutex> lock(m_Mutex);
            // Process event and change state
            m_State = ...;
            newState = m_State;
        }
        m_OnStateChanged(newState);
    }

    // method to allow external objects to connect to the signal etc
private:
    boost::signals2::signal<void (State) > m_OnStateChanged;
    boost::mutex m_Mutex;
    State m_State;
};
Run Code Online (Sandbox Code Playgroud)

问题

如果OnEvent处理程序有多个并发调用,这可能会导致侦听器收到有关状态更改的通知,而不是实际发生的更改.状态本身受上面的互斥锁保护,因此实际状态是明确定义的.但是,在对信号的调用中不能保持互斥锁,因为这可能导致死锁.这意味着信号的实际调用可能以任何顺序发生,而我要求它们以与实际发生状态变化相同的顺序被调用.

处理此问题的一种方法是从信号中删除状态,并通知侦听器状态已更改.然后,他们可以查询对象的状态,并获得对象在触发信号时的状态或以后的状态.在我的场景中,需要告知侦听器所有状态更改,因此此方法在此处不起作用.

我的下一个方法是如下:

class ObjectWithState {
public:
    enum State { …
Run Code Online (Sandbox Code Playgroud)

c++ multithreading future boost-signals2

5
推荐指数
1
解决办法
1124
查看次数

boost :: signals2 slot作为非静态函数成员?

我最近一直在boost::signals2为学习目的而玩,我想知道我是否可以将信号连接到一个类中的非静态插槽(就像我在Qt中那样).考虑以下:

class Worker {
    typedef boost::signals2::signal<void (const std::string &)> SendMessage;
public:
    typedef SendMessage::slot_type SendMessageSlotType;
    boost::signals2::connection connect(const SendMessageSlotType &slot) {
        return send_message.connect(slot);
    }
private:
    SendMessage send_message;
};

class Controller {
public:
    Controller() {
        worker.connect(&Controller::print);
    }
private:
    static void print(const std::string &message) {
        std::cout << message << std::endl;
    }

    Worker worker;
};
Run Code Online (Sandbox Code Playgroud)

现在我想创建Controller::print一个非静态成员.与boost::thread例如,这可以使用来实现boost::bind; 有没有办法做到这一点boost::signals2

c++ boost non-static boost-signals2

5
推荐指数
1
解决办法
4643
查看次数

boost::signals2 和异常处理

是否有某种方法可以覆盖在 boost::signals2 中调用插槽并执行某些操作(日志记录、调试、异常处理)的特定时刻?

我想在槽调用时捕获异常,因为信号/槽是我的代码中的执行路径在各种软件组件之间交叉的地方,每个组件都是可选的/可以在运行时被禁用,如果它行为不端。因此,当插槽调用抛出(可能来自外部库,可能只是 std::bad_alloc)时,我希望收到有关它的通知——并知道哪个组件被发送到了——这样我就可以终止该组件。

我不知道如何在组合器中做到这一点,因为我无法访问那里的插槽或连接对象?所以我看不到获取任何信息的方法。(在每个插槽上更改返回类型是不可行的。)

有没有一些我错过的超级简单的方法来做到这一点?

如果没有,我该怎么办?

将诸如 slot_call_iterator(在 try/catch 中包装调用)和 connection_body_base(例如存储有关它属于哪个组件的信息)之类的东西子类化,并让 boost 使用这些?(如何?)

或者子类signals2::slot<...>,在构造函数中为其提供有关拥有组件的信息并以某种方式重载operator()(...)?(也不知道这一点,使用所有模板魔法似乎更难。)

c++ boost boost-signals2

5
推荐指数
1
解决办法
711
查看次数

对于简单的应用程序,boost :: signals2是否过度杀伤?

在限制的环境中C++03,boost::signals2与组件一起使用boost::functionboost::bind在组件之间实现简单的消息传递系统.它工作得很好,我也没有任何问题.

但是,在另一个完全支持的环境C++11,boost::signals2对于非常简单的应用程序来说是否过度杀伤?

为了澄清,通过简单的我的意思是下列:

  • 单线程
  • 所有信号都有返回类型 void

性能是这个应用程序的关键,因此boost::signals2应用程序不需要的所有奇迹可能弊大于利.

现在,只需要std::vector<std::function>处理这个,并切换到其他东西,boost::signals2如果它被认为是合适的话会非常简单.

c++ boost signals-slots boost-signals2 c++11

5
推荐指数
1
解决办法
1518
查看次数