代码之家  ›  专栏  ›  技术社区  ›  DalekSupreme

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

  •  3
  • DalekSupreme  · 技术社区  · 11 年前

    我正在尝试用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 回复  |  直到 11 年前
        1
  •  3
  •   Community CDub    5 年前

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

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

    #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 .

        2
  •  0
  •   πάντα ῥεῖ    11 年前

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

    如果您需要一个更轻量级的智能指针实现 环境,安德烈·亚历山德雷斯库的 Loki Library 可能对你有用。至少在有限的系统环境中,我已经成功地将其无缝集成(比使用boost更好、更容易)。

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