2014-10-10 2 views
1

Так что я класс, который определяет TileGrid:C++ Вызов функции, которая имеет шаблон, который имеет наследство

template<typename T> 
class TileGrid { ... }; 

заливаю шаблон с классом под названием ImageTile

class ImageTile { ... }; 

У меня есть ребенок класс ImageTile, что я определил, что выглядит следующим образом:

class FFTWImageTile : public ImageTile { ... }; 

В отдельном файле я определяю следующие функции:

void writeDataToFile(TileGrid<ImageStitching::ImageTile> * grid, std::string fileName); 

(примечание: как ImageTile и FFTWImageTile находятся в пространстве имен ImageStitching)

Теперь все вышеперечисленное компилируется нормально, но когда я пытаюсь использовать его Я получаю сообщение об ошибке.

Вот пример тест, который использует его:

namespace is = ImageStitching; 
TileGrid<is::FFTWImageTile> * grid = new TileGrid<is::FFTWImageTile> (...); 
writeTranslationsToFile(grid, "output.txt"); 

При составлении тестового примера я получаю следующее сообщение об ошибке:

error: cannot convert ‘TileGrid<ImageStitching::FFTWImageTile>*’ to ‘TileGrid<ImageStitching::ImageTile>*’ for argument ‘1’ to ‘void writeTranslationsToFile(TileGrid<ImageStitching::ImageTile>*, std::string)’

Во всяком случае, я могу сделать это случиться в C++ ?? Я просмотрел все и не могу найти помощь в создании функции с параметром, содержащим шаблон с дочерними/родительскими отношениями.

Edit: ответы

Всеобщие были исключительными, и каждый решает этот вопрос представлен. Я думаю, решил перейти на C++ 11 и использовать assert для этого конкретного случая. В будущем, я думаю, я добавлю шаблон к функции и обеспечиваю получение данных таким образом. Спасибо всем за помощь! Я отметил, что я считаю лучшим ответом, хотя каждый из них был приемлемым.

ответ

2

Вы получаете ошибку, потому что несмотря на то что FFTWImageTile происходит от ImageTile, TileGrid<FFTWImageTile> и TileGrid<ImageTile> абсолютно несвязанные классы.

Как исправить это, зависит от реализации классов, которые вы не указали. Может быть, вы можете сделать writeDataToFile() шаблонный:

template<typename T> 
void writeDataToFile(TileGrid<T> * grid, std::string fileName); 
+0

К сожалению, мне нужны конкретные атрибуты, которые можно получить из класса ImageTile. Если бы я мог предположить, что typename T будет некоторым типом ImageTile, то я думаю, что я мог бы добавить writeDataToFile внутри TileGrid. Например, в java Jameshobbs

+1

@Jameshobbs вам не нужно делать это, просто предположите это в коде, и если вы передадите что-то, что не является «ImageTile», оно просто не будет компилироваться. –

+0

@Jameshobbs, а также, если вам нужно 'ImageTile', почему бы не передать его' writeDataToFile'? –

0

Вы генерировать два различных класса с

TileGrid<ImageStitching::ImageTile> 

и

TileGrid<is::FFTWImageTile> 

Они не имеют никакого отношения, кроме генерируется из того же шаблона. Вы бы хотели получить из класса TileGrid<ImageStitching::ImageTile>, чтобы иметь фактический подкласс для целей типа.

Вы можете templatize функции writeDataToFile, но для принудительного ограничения типов на аргументы шаблона вы должны использовать что-то вроде ...

static_assert(is_base_of<T, ImageStitching::ImageTile>>(), "T is not a base of ImageTile"); 
+0

К сожалению, для меня is_base_of является стандартом C++ 11. Каков статус C++ 11, полезно ли включить поддержку? – Jameshobbs

+0

Вы должны обязательно использовать C++ 11/14, если сможете. Поддержка компилятора для 11 довольно обширна (VS все еще может не хватать нескольких вещей, GCC и Clang, как правило, имеют полный набор функций). Я также пишу Java, и вам, вероятно, будет немного удобнее использовать C++ 11. – Jason

+0

Спасибо за предложение. Еще одна вещь, которую я могу донести до моего начальника относительно того, почему мы должны переключиться на C++ 11/14: D. – Jameshobbs

0

Варианты, которые могли бы работать для вас.

  1. writeDataToFile шаблон функции.

    template <typename T> 
        void writeDataToFile(TileGrid<T> * grid, std::string fileName); 
    

    При реализации этой функции используйте другой шаблон функции для записи отдельных элементов плитки.

    template <typename T> 
        void writeTileElement(T const& tileElement, std::ostream& out); 
    

    Вы можете создавать перегружена версию writeTileElement позаботиться о специальной обработке различных типов объектов.

  2. Использовать TileGrid от ImageTile* вместо ImageFile.

    void writeDataToFile(TileGrid<ImageStitching::ImageTile*> * grid, std::string fileName); 
    
Смежные вопросы