3

我需要能夠對模板的任何專業的存儲在一個變量如:C++變量保存類模板的任何專業的

template<T> 
class Grid { 
    int GetRows(); 
    int GetTypeOfColumn(int col); 
    //...etc... 
} 

//EDIT: 
Grid<int>::GetTypeofColumn(int col) { 
    return col == 0 ? STRING_COL_TYPE : INT_COL_TYPE; 
} 
Grid<string>::GetTypeofColumn(int col) { 
    return STRING_COL_TYPE; 
} 
//End EDIT 

class Foo { 
    Grid<int>* aBunchOfNumbers; 
    Grid<string>* aBunchOfStrings; 
    //...etc... 
} 

//in some function, say `wants` is an enum, and foo is gotten from somewhere: 
Foo* foo; 
switch wants { 
    case NUMBERS: 
    std::cout << "Rows: " << foo->aBunchOfNumbers->GetRows() << std::endl; 
    std::cout << "Col0 is: " << foo->aBunchOfNumbers->GetTypeofColumn(0) << std::endl; 
    //...etc... 
    break; 
    case STRINGS: 
    std::cout << "Rows: " << foo->aBunchOfNumbers->GetRows() << std::endl; 
    std::cout << "Col0 is: " << foo->aBunchOfNumbers->GetTypeofColumn(0) << std::endl; 
    //...etc... 
    break; 
} 

它會更容易做到:

Foo* foo; 
Grid* grid; 
switch wants { 
    case NUMBERS: 
    grid = foo->aBunchOfNumbers; 
    break; 
    case STRINGS: 
    grid = foo->aBunchOfStrings; 
    break; 
} 
std::cout << "Rows: " << grid->GetRows() << std::endl; 
std::cout << "Col0 is: " << grid->GetTypeofColumn(0) << std::endl; 
//...etc... 

以同樣的方式,如果我使用這樣的子類:http://ideone.com/MPKy1w

我知道類模板幾乎基本上是宏和編譯器如何實際編譯它們,但是沒有一般參考專業化並保存重複的方法?

(我用三分球故意在這裏,我有我的實際代碼沒有選擇,我不能在這裏複製)

+3

你想要一些多態性。有靜態(重載,模板)和動態(虛擬功能)。只需選擇一個。 –

+0

但是,多態性,他不需要爲他想包含的每個新類定義派生類嗎? – Stephen

+0

@Stephen不包含模板 – jaggedSpire

回答

6

與所需的方法創建類(「接口」)。

class GridOperations { 
    virtual int GetRows() = 0; 
    virtual int getTypeOfColumn(int col) = 0; 
    virtual ~GridOperations() {} 
}; 

現在從上面的類繼承電網:

template<T> 
class Grid : public GridOperations { 
    int GetRows() { /* impl */ } 
    int GetTypeOfColumn(int col) { /* impl */ } 
}; 

現在你可投兩Grid<int>*Grid<string>*GridOperations*:因爲你的方法不依賴於模板參數T這是可能做到

Foo* foo; 
GridOperations* ops; 
switch wants { 
    case NUMBERS: 
    ops = foo->aBunchOfNumbers; 
    break; 
    case STRINGS: 
    ops = foo->aBunchOfStrings; 
    break; 
} 
std::cout << "Rows: " << ops->GetRows() << std::endl; 
std::cout << "Col0 is: " << ops->GetTypeofColumn(0) << std::endl; 

加成:你甚至可以使用std::map<WantEnumType, GridOperations*>來避免令人討厭的開關閉鎖。

+0

謝謝,有一個參數類型爲T的方法,例如。 'GetValue(T * obj)',它在一個也需要T類型的函數中調用? http://pastebin.com/BqTNQ8iD –

+0

在這種情況下,您將'someMemberFunction'聲明爲函數模板:[http://pastebin.com/RwSqxitR](http://pastebin.com/RwSqxitR)。想法是,如果你的班級/功能取決於水平。模板化,那麼它(類/功能)也必須被模板化。您還必須明白,從編譯器的角度來看,「Grid 」和「Grid 」是兩個不同的類(如Robot,PricingPolicy和GreenException)。模板是創建具有類似功能和類的_families_以避免單獨編寫它們的方法。 – gudok