“运行时模板”

时间:2010-11-20 14:55:54

标签: c++ templates polymorphism

我很确定答案是“你不能使用模板,你必须使用虚函数(动态多态)”,但似乎我必须复制很多代码,如果我去那条路线。这是设置:

我目前有两个类,ColorImageSegmentation和GrayscaleImageSegmentation。它们基本上做同样的事情,但有三个不同之处 - 它们在不同类型上运行(ColorImage和GrayscaleImage) - 参数,直方图的维数(3对1)是不同的 - PixelDifference功能因图像类型

而异

如果我创建了一个类

template <TImageType>
class ImageSegmentation
{
};

我会保持良好状态。但是,我希望将此对象作为另一个类的成员:

class MyMainClass
{
 ImageSegmentation MyImageSegmentation;
};

但是用户需要确定MyImageSegmentation的类型(如果用户打开灰度图像,我想实例化MyImageSegmentation<GrayScaleType>。同样对于彩色图像,MyImageSegmentation<ColorType>。< / p>

使用派生类,我可以存储指针,然后执行:

class MyMainClass
{
 ImageSegmentation* MyImageSegmentation;
};

... user does something...
MyImageSegmentation = new ColorImageSegmentation;

但是如何使用模板执行此类操作?问题是我有很多:

typedef TImageType::HistogramType HistogramType;
typedef TImageType::PixelType PixelType;

有些事情正在发生,所以我不知道如何将它们转换为动态多态模型而不重复一大堆代码。

抱歉漫无目的......有没有人对我有任何建议?

谢谢,

大卫

2 个答案:

答案 0 :(得分:5)

也许您还没有告诉我们其他要求,但是从目前为止,您可以通过包含类传递类型:

template<typename TImage>
class MyMainClass
{
   ImageSegmentation<TImage> MyImageSegmentation;
};

最有可能你需要一些动态调度层,但只是在最高抽象层次上:

struct IMainClass
{
   virtual bool SaveToFile(std::string filename) = 0;
   virtual bool ApplySharpenFilter(int level) = 0;
   ...
};

template<typename TImage>
class MyMainClass : public IMainClass
{
   ImageSegmentation<TImage> MyImageSegmentation;
public:
   virtual bool SaveToFile(std::string filename);
   virtual bool ApplySharpenFilter(int level);
};

IMainClass* pMain = new MyMainClass<GrayscaleImage>();

答案 1 :(得分:1)

您想要创建对象的模板化版本,但是这些对象是否根据模板化参数采用不同的参数类型?这对于集成到库中并不是一件容易的事情,但有几种方法可以解决它。

看一下unary_function的灵感。在那里,他们使用模板化特征来携带类型参数,而不必使用任何魔法:

template <class Arg, class Result>
  struct unary_function {
    typedef Arg argument_type;
    typedef Result result_type;
  };

'unary_function'不包含除声明typedef之外的任何功能。但是,这些typedef允许您在代码和编译时表示代码段之间的等效命名。他们利用模板参数的检查方式。

这意味着您可以拥有对此有用的对象:

template<typename T>
struct Foo{
    typedef typename T::argument_type argument_type;
    Foo(T _myFunc) : m_Func(_myFunc)
    void myWrappedFunction(argument_type _argument){ m_Func( _argument ); }
};

其中包含参数的值类型,而不必事先指定它们。因此,如果您的每个图片对象都有pixel_type或类似内容,那么只需说明typename T::pixel_type即可调用您需要的类型参数。