2014-10-10 49 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); 

(注:兩個ImageTileFFTWImageTile都在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++ ??我看了遍,並不能似乎找到一些幫助,製造具有特色的有父/子關係的模板參數的函數。

編輯:

每個人的答案都十分優秀,並且每個解決這一問題提出的。我認爲決定遷移到C++ 11併爲這個特定情況使用assert。在未來,我想我會一個模板添加到功能,確保獲取數據的方式。謝謝大家的幫助!我已經標記了我認爲最好的答案,儘管每個答案都可以接受。

回答

2

由於儘管FFTWImageTile來自ImageTileTileGrid<FFTWImageTile>TileGrid<ImageTile>是絕對不相關的類,您仍然收到錯誤。

如何解決這個問題要看你沒有表現出類的實現。也許你可以讓writeDataToFile()模板:

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

不幸的是我需要的是從ImageTile類得到特定屬性。如果我可以推斷typename T是某種類型的ImageTile,那麼我認爲我可以在TileGrid中添加writeDataToFile。例如,在Java Jameshobbs 2014-10-10 18:44:04

+1

@Jameshobbs中,您不必推斷它,只要在代碼中假設它,並且如果傳遞的不是'ImageTile',它就不會編譯。 – 2014-10-10 19:02:26

+0

@Jameshobbs以及,如果你需要'ImageTile'本身,爲什麼不把它傳遞給'writeDataToFile'? – 2014-10-10 19:04:05

0

您生成兩個不同的班級,

TileGrid<ImageStitching::ImageTile> 

TileGrid<is::FFTWImageTile> 

他們沒有不是從同一模板產生的其他關係。你會想從類TileGrid<ImageStitching::ImageTile>導出到有型目的的實際子類。

你可以模板化的功能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 2014-10-10 19:01:12

+0

如果可以的話,你一定要使用C++ 11/14。編譯器對11的支持相當全面(VS可能仍然缺少一些東西,GCC和Clang通常功能完整)。我也編寫Java,你可能會更習慣於使用C++ 11。 – Jason 2014-10-10 19:05:29

+0

感謝您的建議。還有一件事我可以提交給我的老闆,爲什麼我們應該改用C++ 11/14:D。 – Jameshobbs 2014-10-10 19:17:28

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. 使用ImageTile*TileGrid而不是ImageFile

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