"接口与QUOT;喜欢用的boost ::绑定语义 [英] "Interface" like semantics with boost::bind

查看:202
本文介绍了"接口与QUOT;喜欢用的boost ::绑定语义的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望能够有东西像C ++ Java的接口语义。起初,我用了的boost ::信号回调明确登记的成员函数对于给定的事件。这确实行之有效。

I wanted to be able to have something like Java's interface semantics with C++. At first, I had used boost::signal to callback explicitly registered member functions for a given event. This worked really well.

但后来我决定,函数回调的一些池均与它抽象有意义他们,一次注册的所有实例的相关的回调。但我了解到的是,的boost ::绑定和/或获取价值的具体性质这个似乎作出这样的突破。也许这就是刚才说的 add_listener(X安培; X)的事实方法声明中改变了code,它的boost ::绑定生成的。

But then I decided that some pools of function callbacks were related and it made sense to abstract them and register for all of an instance's related callbacks at once. But what I learned was that the specific nature of boost::bind and/or taking the value of this seemed to make that break. Or perhaps it was just the fact that the add_listener(X &x) method declaration changed the code that boost::bind generated.

我有一个非常粗略的了解,为什么出现问题,我认为这可能是正常按照它的设计。我很好奇:什么的我做了呢?当然,有一个正确的方式来做到这一点。

I have a very rough understanding why the problem occurred and I think it's probably functioning correctly as per its design. I am curious: what should I have done instead? Surely there's a Right Way to do it.

下面是一些例子code:

Here's some example code:

#include <boost/bind.hpp>
#include <boost/function.hpp>
#include <iostream>

using namespace std;

struct X;
struct Callback
{
    virtual void add_listener(X &x) = 0;
};

struct X
{
    X() {}
    X(Callback &c) {  c.add_listener(*this); }
    virtual void go() { cout << "\t'" << __PRETTY_FUNCTION__ << "'" << endl; }
};

struct CallbackReal : public Callback
{
    virtual void add_listener(X &x)
    {
        f = boost::bind<void>(boost::mem_fn(&X::go), x);
    }

    void go() { f(); }

    boost::function<void (void)> f;
};


struct Y : public X
{
    Y() {}

    Y(Callback &c) {  c.add_listener(*this); }
    virtual void go() { cout << "\t'" << __PRETTY_FUNCTION__ << "'" << endl; }
};


int main(void)
{
    CallbackReal c_x;
    CallbackReal c_y;

    X x(c_x);
    Y y(c_y);

    cout << "Should be 'X'" << endl;
    boost::bind<void>(boost::mem_fn(&X::go), x)();

    cout << "Should be 'Y'" << endl;
    boost::bind<void>(boost::mem_fn(&X::go), y)();

    cout << "------------------" << endl;

    cout << "Should be 'X'" << endl;
    c_x.go();
    cout << "I wish it were 'Y'" << endl;
    c_y.go();

    return 0;
}


好吧,我并没有完全说明问题。标题是误导性的。


Okay, I did not describe the problem completely. The title is misleading.

哦,伙计。 Downvote这一个。我显然还没有描述的问题很好,我想这最终归结为一个主要语法错误。 (

推荐答案

的boost ::绑定按价值计算,它们拷贝需要它的参数。这意味着

boost::bind takes its parameters by value and copies them. That means

f = boost::bind<void>(boost::mem_fn(&X::go), x);

将传递一个的复制的的 X ,将切下的片它(如果它真的是一个来开头)。为了得到虚拟调度工作,你需要一个指针传递给的boost ::绑定

will pass a copy of x, which will slice off the Y piece of it (if it was really a Y to begin with). To get virtual dispatch to work, you need to pass a pointer to boost::bind:

f = boost::bind(&X::go, &x);

(请注意,您实际上并不需要的mem_fn ,或明确写入&LT;无效&GT; ,因为的boost ::绑定和参数推导照顾那些对你的。)

(Note that you don't actually need mem_fn, or to explicitly write <void>, since boost::bind and argument deduction take care of those for you.)

这篇关于&QUOT;接口与QUOT;喜欢用的boost ::绑定语义的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆