存储一个具有先前未知模板的通用对象
我想在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*)
{
}
}
回答:
好吧,我明白正是你需要的。你只需要一个简单的回调操作符,具有固定的呼叫签名。
这个例子演示了它是如何为您的特定情况下完成的:
#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。
回答:
确实有比他们提供与原标准(std::auto_ptr
)智能指针更复杂的实现。但他们都涉及一些更复杂的概念(主要是关于共享指针的引用计数)。有什么阻碍使用这些?
如果您需要在c++03环境中实现更轻量级的智能指针实施,Andrei Alexandrescu的Loki Library可能对您有用。至少我已经设法将它无缝集成到有限的系统环境中(比使用boost更好,更容易)。
甚至不要尝试完全靠自己完成,有很多很多缺陷... 如果您能够启用c++11标准,只需使用这些!
以上是 存储一个具有先前未知模板的通用对象 的全部内容, 来源链接: utcz.com/qa/262858.html