简体   繁体   English

基于基本功能的模板操作

[英]Template operation on base function

I have an interface IImage , which is derived by a template class CTypedImage , whith the pixel type as template argument. 我有一个接口IImage ,该接口由模板类CTypedImage派生,其中像素类型作为模板参数。

class IImage
{
public:
    virtual ~IImage() {}
    ...

    static int IImage::ReadFile(IImage* &outImage, QString path, QString file);
};

template<class T>
class CTypedImage : public IImage
{
    ...
};

This way, I can just call: 这样,我可以打电话给:

IImage* image = nullptr;
int ret = IImage::ReadFile(image, path, file);

without knowledge of the underlying pixel type. 不了解底层像素类型。

This piece of code is generic and may be used in many projects, so I don't want to implement specific processings in it. 这段代码是通用的,可以在许多项目中使用,所以我不想在其中实现特定的处理。

Instead, I want to localy define the operations to apply on the data. 相反,我想在本地定义要应用于数据的操作。 The problem is that in my main code, I don't have acces to the type of pixel (and I don't want to handle it if it's not necessary), so I can't just call 问题在于,在我的主代码中,我不了解像素的类型(如果不需要,我也不想处理它),所以我不能只调用

OperationOnData<type_of_pixel>(image);

I tried with this idea: 我尝试过这个想法:

  • Adding a function CallOperation to the interface IImage : 将函数CallOperation添加到接口IImage

     virtual int CallOperation(class IOperation* op) = 0; 

    with

     class IOperation { public: virtual ~IOperation() {} virtual int Apply(IImage* img) = 0; }; 
  • Define the specific operations locally: 在本地定义特定的操作:

     template<class T> class MyOperation: public IOperation { public: MyOperation() {} ~MyOperation() {} int Apply(IImage* img); }; template<class T> int MyOperation::Apply(IImage* img) { /* do things with pixels of type T */ } 
  • Call the operation with the type as a template argument:: 以类型作为模板参数调用该操作:

     template<class T> int CTypedImage<T>::CallOperation(IOperation* op) { if (op == nullptr) return -1; return op->Apply<T>(this); } 

But all the variations I tried around this idea did not work, either because it did not compile (for example because I can't have a virtual fonction in a template) or it doesn't use the derived Apply function. 但是我尝试过的所有变体都没有用,因为它没有编译(例如,因为我无法在模板中使用虚拟功能),或者没有使用派生的Apply函数。

I tried different syntaxes, but I can't find a way to achieve what I want. 我尝试了不同的语法,但是找不到找到想要的方法。

Any help will be greatly appreciated, even telling me I need to rewrite all the thing. 任何帮助将不胜感激,甚至告诉我我需要重写所有内容。

Add an accept virtual function to your CTypedImage like this: 将接受虚拟函数添加到您的CTypedImage中,如下所示:

template<class T>
class CTypedImage : public IImage
{

    ...
   virtual void accept(IOperation *operation)
   {
       operation->Apply(this) ;
   }
};

Your operation then will be defined like this: 然后,您的操作将如下定义:

class IOperation
{
public:
    virtual ~IOperation() {}
    virtual int Apply(CTypedImage<char> * img) = 0; // one function for every kind of pixel
    virtual int Apply(CTypedImage<short> * img) = 0; // a typelinst could be handy 
                            // while defining the type set but that's another story
};

A concrete operation may be defined like this 可以这样定义一个具体的操作

class MyIOperation : public Operation
{
public:
    virtual ~IOperation() {}
    virtual int Apply(CTypedImage<char> * img) 
    {                      // forward to generic implementation
        ApplyT(img) ;      // note: image type is known here 
    }
    virtual int Apply(CTypedImage<short> * img) 
    { ApplyT(img) ;}      

    template <class T>
    int ApplyT(CTypedImage<T> * img)
    { 
        // generic implementation
    }
};

So given a pointer to an operation and a generic image you can apply the operation like this 因此,给定指向操作的指针和通用图像,您可以像这样应用该操作

IOperation *operation ;
IImage *image ;

image->accept(operation) ;

This is an application of the visitor pattern , where the operation act as visitor. 这是访问者模式的一种应用,其中操作充当访问者。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM