2014-09-30 67 views
1

(我讀過關於這個問題的幾個存在的問題,他們似乎略有不同,不要使這個問題更清楚給我。)矢量模板類的

我試圖創建密鑰的矢量值是通用的值對。這邏輯表示什麼,我需要的代碼如下:

#include <stdio.h> 
#include <string.h> 
#include <vector> 

template <typename T> 
class CCmd 
{ 
    protected: 
     char name[64]; 
     T value; 

    public: 
     CCmd(char* _name, T _value) 
     { 
      strcpy(name, _name); 
      value = _value; 
     } 

     T getValue() 
     { 
      return value; 
     } 

     void setValue(T _value) 
     { 
      value = _value; 
     } 
}; 

int main() 
{ 
    std::vector<CCmd*> vec; 

    vec.push_back(new CCmd<int>("gravity", 150)); 
    vec.push_back(new CCmd<char*>("configfile", "config.cfg")); 

    printf("Value = %d\n", vec[0]->getValue()); 
    printf("Config = %s\n", vec[1]->getValue()); 

    return EXIT_SUCCESS; 
} 

這種失敗在各個方面我認爲這將是語法正確編譯。我讀了一個問題,使用一個基類來封裝通用類是必需的,但是我所指示創建一個空的類嘗試這樣做,讓我的泛型類它的一個子類:

... 
class CCmdBase 
{ 
}; 

class CCmd : public CCmdBase 
{ 
... 

和編譯器抱怨那CCmdBase沒有一個名爲getValue的成員,因爲它返回泛型類型T,這意味着基類也需要是泛型的,以便在其中定義它,這意味着我回到了我所在的位置開始了嗎?

請幫忙;我在這裏錯過了什麼?

+0

您不會錯過太多。我會完全放棄吸氣劑和吸氣劑,並使用訪問者模式進行檢查。 – 2014-09-30 18:51:32

+0

因爲CCmd是一個模板類 - 是不是這個錯誤:「std :: vector 」? – Matthias 2014-09-30 18:55:11

+1

@Matthias是的,我寫了「邏輯表示」我需要的代碼。 – Doddy 2014-09-30 18:56:12

回答

4

你的方法不能用C++輕鬆完成。很可能你的設計不正確,應該改進。很難提供確切的方法,但是可能的解決方案是使用純虛函數來獲得抽象基類。雖然您的虛擬功能在您當前的「設計」中不能爲setValuegetValue,因爲函數簽名必須與虛擬功能匹配。

如果您確實需要在向量中使用不同的值實現方法,請查看std::tuple,boost::variantboost::any。同樣不要指望這種解決方案的使用對您來說很容易理解和明確。

+0

TBQH,我覺得這是一個在那些OP的設計本質上沒有缺陷的罕見場合中,但受到C++中各種特性的限制。請理解:我不這麼說,我不經常這樣說! :) – 2014-09-30 23:25:52

2

這是不正確的:std::vector<CCmd*> vec;

您必須指定模板參數類型。 CCmd不是一種類型,它是類模板的名稱。例如,std::vector< CCmd<int> *> vec;

不可能有一個直接存儲不同類型的項目的向量。矢量必須存儲相同類型的項目。你正在尋找的東西叫做異構容器。標準C++沒有任何功能,但可以使用具有檢索「真實」對象功能的通用類型來模擬。

您的想法std::vector<CCmdBase *>將工作,使用運行時多態性。當然,你必須在CCmdBase類中實現你想要的功能。您可以在非模板類定義中使用模板函數,例如:

struct CCmdBase 
{ 
    template<typename T> T getValue() 
    { 
     return dynamic_cast< CCmd<T> & >(*this).getValue(); 
    } 

    virtual ~CCmdBase() {} 
}; 
+0

因爲無論如何你必須在從基類中調用'getValue()'時明確指定類型,所以你也可以使用static cast:'static_cast const&>(* this).getValue()'。 – davidhigh 2014-09-30 20:15:01

+0

@davidhigh好的,儘管如果你指定錯誤的類型會導致UB。在這種情況下,我會拋出異常。 – 2014-09-30 20:45:17

+0

這就是爲什麼我建議訪客模式。 – 2014-09-30 23:24:58