2010-01-12 84 views
2

我有一個接口C++模板:防止基本模板的實例

std::string 
get_string(Source const &s, std::string const &d); 
int 
get_int(Source const &s, int const &d); 
bool 
get_bool(Source const &s, bool const &d); 

我想改變

template<class T> 
T 
get(Source const &s, T const &d); 

其中有沒有合理的基礎模板,所以實際的基礎定義是合法但無用的(return d;)。如果基礎實例化,我能做些什麼來強制編譯時失敗?這種情況是否有一種習慣解決方案?

+1

* base模板*是什麼意思?另外請記住,功能模板不專門化,但過載。 – 2010-01-12 17:30:41

+0

「基本模板」與「專業化」相對 – 2010-01-12 18:14:45

+1

如果您不想定義「基本模板」,則無需向模板中添加模板。你最初的想法是爲各種類型提供重載是正確的。 – 2010-01-12 19:00:04

回答

10

不要定義模板,只需聲明它並定義三個特化。

template <typename T> 
T get(Source const &, T const &); 

template<> 
std::string get(Source const &s, std::string const &d) { 
    return d + s.stringval(); // or whatever 
} 

[編輯:刪除有關重載的東西 - 只是一次,模板功能專業化確實似乎更好。誰會想要?]

+0

隱式轉換是模板的原因 – 2010-01-12 17:44:11

+0

您的意思是調用者應該始終指定類型,而不是永遠允許從參數中推斷它嗎? – 2010-01-12 18:00:53

+0

我的意思是我希望所選功能與實際類型完全匹配 – 2010-01-12 18:12:02

-1

將基類(t)聲明爲抽象,這樣一個實例永遠不能創建該類。

+0

這個問題是關於自由函數的,而不是類 – 2010-01-12 17:50:37

3

只是做

string get(source, string); 
int get (source, int); 
bool get(source, bool); 
+0

,它打開了一堆蠕蟲,因爲'bool'和'int'可以隱式地來回轉換。 – 2010-01-12 17:48:20

+0

沒問題,當正確的未轉換過載可用時,編譯器不會隱式轉換它們。 – 2010-01-12 18:59:25

0

如果你願意支付運行時多態性,你可以做到這一點...

template <typename T> 
class Interface 
{ 
    virtual T get(Source const &s, T const &d) = 0; 
}; 

class StringInterface : public Interface<std::string> 
{ 
    virtual std::string get(Source const& s, std::string const& d); 
}; 

// etc. 

因爲你的基礎是一個抽象類,你會得到如果您嘗試直接實例化編譯時失敗。