2011-12-11 88 views
0

假設我有一個類,如下面定義的Value一個接口可以只指定方法名稱,但不能返回類型?

template <typename T> 
class Value : public ValueInterface 
{ 
    public: 
     // ... 
     T getValue() const; 

    private: 
     T value_; 
} 

我可以在我的代碼是指多個Value期不同類型(即不同類型的T)的一般(創建一個容器,例如)?我首先想到的是,如果有可能以某種方式聲明一個純抽象類從Value可以繼承:

class ValueInterface 
{ 
    public: 
     ?? getValue() const = 0; 
} 

template <typename T> 
class Value : public ValueInterface 
{ 
    // ... 
} 

std::list<ValueInterface> lst; 
Value<int> i(...); 
Value<char> c(...); 

lst.push_back(i); 
lst.push_back(c); 

int vi = i.getValue(); 
char vc = c.getValue(); 

如果是不可能的,你能提供一個替代的解決方案?

+2

你可以給一個僞代碼如何使用這樣的功能的例子嗎? –

+0

它就在那裏,在第二個片段。我需要聲明一個'std :: list'來存放不同的'Value'。 –

+0

但是,這與你的'getValue'方法有什麼關係? –

回答

1

在C++中,所有表達式都必須具有編譯器已知的類型,但在您的解決方案lst.begin()->getValue()中不會有任何特定的類型。

雖然如果你仔細看看你的例子,你不會在任何地方調用ValueInterface::getValue(),只是子類的版本。

你可以嘗試以下方法:

class ValueInterface 
{ 
    public: 
    template <typename T> 
    T getValue() const 
    { 
     return dynamic_cast< const Value<T> &>(*this).getValue(); 
    } 
    virtual ~ValueInterface() 
    { } 
}; 

template <typename T> 
class Value : public ValueInterface 
{ 
    public: 
     // ... 
     T getValue() const; 

    private: 
     T value_; 
}; 

注意getValue()不是(也不可能是)虛。

現在你可以從你的例子寫的代碼,也:

int z = lst.begin()->getValue<int>(); 

如果您在getValue調用,那麼一個異常std::bad_cast將被拋出使用錯誤的類型。

+2

您需要至少一個用於'dynamic_cast'的虛函數才能工作。 – Xeo

+0

@Xeo好點。析構函數是這裏最好的選擇。更新。 – rodrigo

0

您不能在返回類型上重載,因爲這會造成各種不明確之處。

我不太清楚你想在這裏做什麼。我假設你將遍歷blah或從中選取一個隨機元素,然後在所述元素上調用getValue()。此通話可能會返回任何類型:charconst void*Value< Value< Value<const void*> > >等。您將如何處理結果?你甚至會爲它定義一個變量?

+0

使用blah的函數將知道哪些元素返回什麼類型,並相應地聲明變量。 –

+0

@Dan:如果你有編譯時知道你正在使用的變量的類型,你首先不需要多態。 – suszterpatt

相關問題