模板函数成员变量

时间:2018-12-04 03:11:20

标签: templates variables member

我的目的是设计网络通信中的事件回调模型,该事件回调包括“ recv,发送,接受,关闭...”

class client
{
public:
    template<typename F1>
    void bind_recv(F1 && f)
    {
        // How to save the parameter of bind_recv function in _recv_callback member variable ?
        _recv_callback = f;
    }
    // bind_send
    // bind_accept
    // bind_shutdown
    // ...

protected:
    void notify_recv()
    {
        _recv_callback();
    }
    // notify_send
    // ...

    // How to declare the type of these variable ?
    F1 _recv_callback;
    // F2 _send_callback;
    // ...
};

int main()
{
    client c;
    c.bind_recv([](uint8_t * data, size_t len)
    {

    });


    return(0);
}

我需要保存回调并在正确的时间调用它们,但是每个回调函数的参数都不同,那么如何保存它们?

我想也许我的想法是错误的,那么如何更改设计以满足这一要求?

1 个答案:

答案 0 :(得分:0)

您不能声明模板成员变量。但是,即使可以使用模板类型_recv_callback声明F1,也必须在编译时确定F1。那么client::bind_recv

中的赋值运算符会发生什么
 _recv_callback = f;

当传递的参数f的类型不是_recv_callback

即使您能够为_recv_callback定义一个赋值运算符,该赋值运算符在右侧允许使用不同的类型,也可以“丢失”一些信息。具体来说,分配后,您将不再知道f的类型。更糟糕的是,f可能有一些额外的成员变量,您无法存储在_recv_callback中。

解决这些问题的方法是,首先定义要传递给f的允许参数client::bind_recv的通用“基”(可能是抽象)类。然后,您可以使用多态来处理不同的情况。示例:

#include <memory>    

class callback {

// Some purely virtual functions for a generic interface
virtual ~callback { }
};

class recv_callback : callback {
// Specific implementations of pure virtual members declared in callback
virtual recv_callback;
};

class client
{
public:
    void bind_recv(callback *f)
    {
        _recv_callback.reset(f);
    }

protected:

    std::unique_ptr<callback> _recv_callback;

}

通过传递指向client::bind_recv的指针,可以避免不知道如何处理未知类型的f的问题:您需要传递已经分配的对象。 另外,请注意,我为_recv_callback使用了智能指针,以确保不会泄漏内存。