gpt4 book ai didi

c++ - 不包括 boost 信号调用

转载 作者:行者123 更新时间:2023-11-30 02:12:40 32 4
gpt4 key购买 nike

有一个信号和几个带槽的对象。当一个对象调用信号并阻止它自己的连接时,我想实现这种行为。我想一个小片段会提供更多信息:


typedef boost::signal<void()> TSignal;

template<class TSignal>
class SlotObject
{
public:

void Connect(boost::shared_ptr<TSignal> pSignal, boost::function slot)
{
m_connection = pSignal->connect(slot);
m_pSignal = pSignal;
}

// How to define TSignal signature here?
VOID Call()
{
m_connection.block();
(*m_pSignal)();
m_connection.unblock();
}

boost::shared_ptr<TSignal> m_pSignal;
boost::signals::connection m_connection;
};

问题:

  1. 是否有一些 boost 内容的标准方法?我要重新发明轮子吗?
  2. 如何定义带有TSignal签名的Call方法?

最佳答案

对于您的第一个问题:我不知道实现您想要的目标的“标准 boost 方式”。您可以将您的问题发布到 boost users mailing list .

对于你的第二个问题:没有可变模板和右值引用,转发总是很麻烦。

一些建议,排名不分先后:

1) 您可以查看 boost/signal.hpp 和 boost/signals/中的文件,以了解如何使用预处理器完成此类工作,但这里有一个部分实现以展示想法(警告:未经测试):

template<size_t Arity, class SignalT>
struct SlotBase;

template<class SignalT>
struct SlotBase<0, SignalT>
{
typedef SignalT::slot_function_type SlotType;

SlotBase(boost::shared_ptr<SignalT> S, SlotType F)
: m_Signal(S), m_Connection(S->connect(F))){};

void operator()()const
{
m_Connection.block();
m_Signal();
m_Connection.unblock()
};

private:
boost::shared_ptr<SignalT> > m_Signal;
boost::signals::connection m_Connection;
};

template<class SignalT>
struct SlotBase<1, SignalT>
{
// as above, except for operator()
// ...

void operator()(typename SignalT::arg1_type arg1)
{
m_Connection.block();
m_Signal(arg1);
m_Connection.unblock();
};
};

template<class SignalT>
struct SlotBase<2, SignalT>
{
// as above, except for operator()
// ...

void operator()(typename SignalT::arg1_type arg1, typename SignalT::arg2_type arg2)
{
m_Connection.block();
m_Signal(arg1, arg2);
m_Connection.unblock()
};
};

// repeat for other arities
// ...

template<class SignalT>
class SlotObject : public SlotBase<SignalT::arity, SignalT>
{
typedef SlotBase<SignalT::arity, SignalT> BaseType;

public:
Slot(boost::shared_ptr<SignalT>S,
typename SignalT::slot_function_type F
) : BaseType(S, F)
{}
};

2) 如果您愿意为 SlotObject 的用户放弃一些语法上的优点,其他事情也是可能的。一种是使用 boost::shared_ptr 文档 (http://www.boost.org/doc/libs/1_40_0/libs/smart_ptr/sp_techniques.html#wrapper) 中显示的技术包装对信号的调用,即,您的 Call() 方法将阻塞 m_connection,并返回一个 shared_ptr 给 m_signal,它有一个自定义删除器来解除阻塞 m_connection .

遗憾的是,这并没有给调用者一个很好的语法。它看起来像:

SlotObject<signal<void(int, float)> > s = ...;
s.Call()->operator()(1, 1.234);

3) 另一种选择是要求用户在调用站点将参数打包在元组中(我在下面使用 boost::fusion::vector),并使用 boost::fusion:::fused打开它们并调用信号。

#include <boost/function_types/parameter_types.hpp>
#include <boost/fusion/include/vector.hpp>
#include <boost/fusion/include/mpl.hpp>
#include <boost/fusion/include/fused.hpp>
#include <boost/signal.hpp>
#include <boost/shared_ptr.hpp>

// Metafunction to extract the Signature template parameter
// from a boost::signal instantiation
// For example, SignatureOf<signal<void(int, float)>::type
// is "void(int, float)"
template<class SignalT>
struct SignatureOf;

template<
typename Signature, typename Combiner, typename Group,
typename GroupCompare, typename SlotFunction
>
struct SignatureOf<
boost::signal<Signature, Combiner, Group, GroupCompare, SlotFunction>
>
{
typedef Signature type;
};

// The SlotObject
template<class SignalT>
class SlotObject
{
public:
typedef typename SignatureOf<SignalT>::type SignatureType;

// Defines the "packed" parameters type corresponding
// to the slot's signature
// For example, for a SignalT of boost::signal<void(int, float)>
// ArgsType is "boost::fusion::vector<int, float>"
typedef typename boost::fusion::result_of::as_vector<
typename boost::function_types::parameter_types<SignatureType>::type
>::type ArgsType;

void Call(ArgsType P)
{
m_Connection.block();
boost::fusion::fused<SignalT&> f(*m_Signal);
f(P);
m_Connection.unblock();
}

//...
};

这将用作:

typedef SlotObject<boost::signal<void(int, float)> > SlotType;
SlotType s = ...;
s.Call(SlotType::ArgsType(1, "foo"));

关于c++ - 不包括 boost 信号调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1542024/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com