我是否可以避免模板化需要模板化成员的类

Can I avoid templating a class which needs to have a templated member?

本文关键字:成员 是否 可以避免      更新时间:2023-10-16

>我有两个类:CFileFinderThread封装一个工作线程,CFileFinderCallbackForwarder线程数据转发到几个可能的外部回调函数之一(具有不同的签名)。回调函数的类型是转发器的模板参数。

CFileFinderCallbackForwarder<zCallBack> forwarder(zcallback);
CFileFinderThread<zCallBack> thread(forwarder);
while (thread.WaitForThread(0) != WAIT_OBJECT_0)
{
    bool eventSignaled = ::WaitForSingleObject(forwarder.getCallbackSignal(), 
                                               DEFAULT_CALLBACK_MILLIS)
                         == WAIT_OBJECT_0;
    forwarder.ExternalCallback(eventSignaled);
}

thread 类保留对转发器实例的引用,并调用转发器中的方法以在其中存储数据 - 但仅限于不以任何方式使用模板参数的方法。根据模板参数,实际上唯一不同的方法是 ExternalCallback

是否可以避免使用转发器使用的回调函数的类型模板化线程类?

或者有什么替代方案?因为线程真的根本不应该关心转发器将如何处理其数据。

转发器类划分为非泛型基类和泛型派生类。显然,非泛型基类应包含所有非泛型数据和操作;派生类应包含 ExecuteCallback 函数。

这允许您使线程类也成为非泛型的。

下面是一个简化但完整的示例:

// non-generic base:
class CFileFinderCallbackForwarderBase
{
private:
    int i;
protected:
    // making the constructor protected here is just good practice:
    CFileFinderCallbackForwarderBase() {}
public:
    void SetData() { i = 0; }
};
// thread class is now non-generic
class CFileFinderThread
{
private:
    // thread class is non-generic because it only uses
    // the base class:
    CFileFinderCallbackForwarderBase* forwarder;
public: 
    CFileFinderThread(CFileFinderCallbackForwarderBase* forwarder) :
        forwarder(forwarder)
    {
    }
    void f()
    {
        forwarder->SetData();
    }
};
// derived class is generic:
template <class T>
class CFileFinderCallbackForwarder : public  CFileFinderCallbackForwarderBase
{
public:
    void ExternalCallback()
    {
        T t;
        t = 0;
    }
};
int main()
{
    CFileFinderCallbackForwarder<int> forwarder;
    CFileFinderThread thread(&forwarder);
    forwarder.ExternalCallback();
}

这种技术的一个积极的副作用可能是减少代码膨胀。