【问题标题】:Templating boost::bind to automatically handle multiple arguments for member function模板 boost::bind 自动处理成员函数的多个参数
【发布时间】:2010-08-19 12:11:42
【问题描述】:

我有一个带有“附加”函数的类,它接受一个函数对象并将其存储到一个集合中。类本身是在函数签名上模板化的。像这样的:

template<class Signature>
class Event
{
public:

 void Attach(boost::function<Signature> signature)
 {
  MySignatures.push_back(signature);
 }

private:

 std::list<boost::function<Signature>> MySignatures;
};

为了演示用法,请考虑以下类:


class Listening
{
public:

 int SomeFunction(int x, int y, int z); 
};

要将Listening 上的函数传递给Event,我需要这样写:


 Event<int(int, int, int)> myEvent;
 Listening myListening;

 myEvent.Attach(boost::bind(boost::mem_fn(&Listening::SomeFunction), &myListening, _1, _2, _3));

因此,我没有对每个可能容易出错的情况都这样做,而是编写了一组宏,如下所示:


 #define EventArgument0(x, y)  boost::bind(boost::mem_fn(x), y)
 #define EventArgument1(x, y)  boost::bind(boost::mem_fn(x), y, _1)
 #define EventArgument2(x, y)  boost::bind(boost::mem_fn(x), y, _1, _2)
 #define EventArgument3(x, y)  boost::bind(boost::mem_fn(x), y, _1, _2, _3)
 #define EventArgument4(x, y)  boost::bind(boost::mem_fn(x), y, _1, _2, _3, _4)

 etc.

然后我可以写:


 myEvent.Attach(EventArgument3(&Listening::SomeFunction, &myListening));

这更容易阅读(我认为)。现在我的问题是:我该怎么写:


 myEvent.Attach(EventArgument(&Listening::SomeFunction, &MyListening));

甚至更好:


 myEvent.Attach(&Listening::SomeFunction, &myListening);

,这样事件 Attach 将神奇地与 中包含的适当数量的参数正确绑定(在此示例中,int(int, int, int))?我对您在这里想到的任何模板元编程魔法持开放态度。

谢谢。

编辑:原来我在这里不需要boost::mem_fn,因为boost::bind是等价的,所以在我的宏中我可以使用:

bind(&MyClass::Hello, myClass, _1, _2, _3);

,而不是:

bind(mem_fn(&MyClass::Hello), myClass, _1, _2, _3);

问题仍然存在:如何将&amp;MyClass::Hello 传递给事件类并使用模板重载来处理_1_2_3 等用于模板化@987654340 的函数原型所隐含的@班级?

【问题讨论】:

标签: c++ events bind variadic-templates variadic-functions


【解决方案1】:

为成员函数中不同数量的参数重载Attach

template<typename R,typename T,typename U>
void Attach(R (T::*pmf)(),U* p))
{
    Attach(boost::bind(pmf,p));
}

template<typename R,typename T,typename U,typename A1>
void Attach(R (T::*pmf)(A1),U* p))
{
    Attach(boost::bind(pmf,p,_1));
}

template<typename R,typename T,typename U,typename A1,typename A2>
void Attach(R (T::*pmf)(A1,A2),U* p))
{
    Attach(boost::bind(pmf,p,_1,_2));
}

如果您还需要处理 const 成员函数,那么您将需要第二组重载。

【讨论】:

  • 太棒了。我稍微改变了它以使用 shared_ptr (所以我可以在触发事件之前保存weak_ptr引用并删除 .expired() 指针)。否则,这是一个很好的解决方案。谢谢。
【解决方案2】:

Attach() 制作成一个模板可以让你做你想做的事。代码变得杂乱无章,但它让你可以随心所欲地调用它。

template<typename A1>
void Attach(A1 a1);

template<typename A1, typename A2>
void Attach(A1 a1, A2 a2);

template<typename A1, typename A2, typename A3>
void Attach(A1 a1, A2 a2, A3 a3);

template<typename A1, typename A3, typename A4>
void Attach(A1 a1, A2 a2, A3 a3, A4 a4);

【讨论】:

    猜你喜欢
    • 2021-07-10
    • 2017-06-10
    • 2014-01-09
    • 1970-01-01
    • 2010-12-27
    • 1970-01-01
    • 1970-01-01
    • 2013-11-12
    • 1970-01-01
    相关资源
    最近更新 更多