使用以前未知的模板存储通用对象

时间:2013-10-17 19:52:02

标签: c++ class templates events c++03

我正在尝试在c ++中创建某种事件处理程序。所以我得到了以下内容:

template<class W> 
delegate<W>* bind(W* obj, void (W::*f)(char*))
{
        return new delegate<W>(obj,f);
}

委托类和此函数完美运行。问题是如何存储与bind函数返回的委托对象?我知道使用boost和c ++ 11这很容易但是如何在不使用它的情况下解决这个问题?我确信它必须是可能的,因为在诸如boost和c ++ 11这些复杂的东西之前它是可能的。

(并且他们也以某种方式在提升中做到了。)

所以我想做的事情:

class Test1
{
    Test1(){}
    ~Test1(){}

    template<class W> 
    bind(W* obj, void (W::*f)(char*))
    {
            myCallBack = new delegate<W>(obj,f);
    }

    private:
        delegate * myCallBack;  //this does not work because I have to define the template but I dont know it know it could be anything

}

class Test2
{
    Test2()
    {
        Test1 t;
        t.bind(this, &Test2::callit);
    }
    ~Test2(){}
    void callit(char*)
    {
    }
}

2 个答案:

答案 0 :(得分:3)

好的,我明白你到底需要什么。您只需要一个简单的回调运算符,具有固定的调用签名。

此示例演示了如何针对您的特定情况执行此操作:

#include <iostream>
#include <utility>
#include <type_traits>
#include <vector>
#include <algorithm>



struct Cb {
    virtual ~Cb(){}
    virtual void call(const char*) = 0;
};
template<class C>
struct CmCb : Cb {
    CmCb( C& c_, void (C::*fn_)(const char*) ) : c(c_),fn(fn_)
    {
    }
    virtual void call(const char* s) {
        (c.*fn)(s);
    }
    C& c;
    void (C::*fn)(const char*);
};

struct A {
    void foo( const char* s ) {
        std::cout<<s<<std::endl;
    }
};

class Test1
{
public:
    Test1(){}
    ~Test1(){delete cb;}

    template<class W> 
    void bind(W* obj, void (W::*f)(const char*))
    {
            cb=new CmCb<W>(*obj,f);
    }

    void callit(const char* s ){
        cb->call(s);
    }

    private:
        Cb* cb;
};

int main()
{
    Test1 t;

    A a;
    t.bind(&a, &A::foo );

    t.callit("hey");
}

如果您需要更复杂的解决方案(通用签名),那么您可以使用boost::any进行某种类型的擦除。

答案 1 :(得分:0)

智能指针确实比原始标准(std::auto_ptr)提供的更复杂。但它们都涉及更复杂的概念(主要是关于共享指针的引用计数)。使用这些产品有什么阻碍?

如果您需要为环境提供更轻量级的智能指针实现,Andrei Alexandrescu的Loki Library可能对您有用。我已经成功地将它无缝集成到有限的系统环境中(比使用boost更好更容易)。

甚至不要试图完全靠自己做,有很多陷阱...... 如果您能够启用标准,请使用这些标准!