"шаблоны времени выполнения" - PullRequest
4 голосов
/ 20 ноября 2010

Я почти уверен, что ответ таков: «вы не можете использовать шаблоны, вы должны использовать виртуальные функции (динамический полиморфизм)», но мне кажется, что если бы я пошел по этому пути, мне пришлось бы дублировать много кода,Вот настройка:

В настоящее время у меня есть два класса, ColorImageSegmentation и GrayscaleImageSegmentation.По сути, они делают одно и то же, но есть три различия - они работают с разными типами (ColorImage и GrayscaleImage) - параметр, размерность гистограммы (3 против 1) различна - функция PixelDifference различается в зависимости от типа изображения

Если бы я создал класс

template <TImageType>
class ImageSegmentation
{
};

, я был бы в хорошей форме.Однако я хочу, чтобы этот объект был членом другого класса:

class MyMainClass
{
 ImageSegmentation MyImageSegmentation;
};

Но пользователю необходимо определить тип MyImageSegmentation (если пользователь открывает изображение в градациях серого, я хочу создать экземпляр MyImageSegmentation<GrayScaleType>. Аналогично для цветного изображения MyImageSegmentation<ColorType>.)

С производными классами я мог бы сохранить указатель и затем сделать:

class MyMainClass
{
 ImageSegmentation* MyImageSegmentation;
};

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

но как бы я сделал что-то подобноес шаблонами?Проблема в том, что у меня много таких вещей:

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

, поэтому я не знаю, как бы преобразовать их в динамическую полиморфную модель без дублирования всего набора кода.

Извините за бессвязные ... кто-нибудь есть какие-либо предложения для меня?

Спасибо,

David

Ответы [ 2 ]

5 голосов
/ 20 ноября 2010

Возможно, есть дополнительные требования, о которых вы нам не сказали, но из того, что у вас есть, вы можете передать тип через содержащий класс:

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 голос
/ 20 ноября 2010

Вы хотите создать шаблонную версию своих объектов, но эти объекты принимают разные типы параметров на основе шаблонного параметра? Это не очень легко интегрировать в библиотеку, но есть несколько способов сделать это.

Взгляните на unary_function для вдохновения. Там они используют шаблонные черты для переноса параметров типа без необходимости использовать магию:

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

'unary_function' не содержит никаких функций, кроме объявления typedefs. Эти определения типов, однако, позволяют вам выражать в коде и во время компиляции именованные эквиваленты между сегментами кода. Они используют способ проверки параметров шаблона.

Это означает, что у вас могут быть объекты, которые работают над этим:

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, вызовите нужный вам параметр типа.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...