2017-07-06 111 views
5

我試圖做一個類將使用特定的數據類型,我想不支持數據類型時編譯時錯誤。模板功能專業化默認

我試圖專門化這樣的模板。

template<> 
float Foo::get<float>(const std::string& key) 
{ 
    return std::stof(key); 
} 

而且把std::static_assert在通用功能,因爲我只需要指定這些類型。

template<class T> 
T Foo::get(const std::string&) 
{ 
    static_assert(false, "unsupported data type"); 
    return T(0); 
} 

不幸的是我得到了編譯錯誤(靜態斷言失敗),即使我有這種類型的專門功能。

我找到了一種方法來處理特定的類型,但它看起來有點愚蠢,它不是通用的。

T Foo::get(const std::string&) 
{ 
    static_assert(
      std::is_same<T,float>::value || 
      std::is_same<T,double>::value || 
      std::is_same<T,bool>::value || 
      std::is_same<T,uint32_t>::value || 
      std::is_same<T,int32_t>::value || 
      std::is_same<T,std::string>::value, 
      "unsuported data type"); 
    return T(0); 
} 
+0

有花哨的技巧('always_false :: value')用於這一目的,但我認爲這是簡單的只是沒有定義主模板。 – cpplearner

回答

1

根據模板參數T,您可以製作static_assert,然後在實例化之前不會評估它,即將精確類型作爲模板參數進行探索的時間。例如

template<class T> 
T get(const std::string&) 
{ 
    static_assert(!std::is_same<T, T>::value, "unsupported data type"); 
    return T(0); 
} 

LIVE

+0

我更喜歡'static_assert(sizeof(T)== -1,「不支持的數據類型」);'爲了更緊湊。另外我相信這是比較常見的方法。 –

+0

我發現並嘗試了這個,但它仍然給我這個編譯時錯誤。 哪裏應該是我在.cpp或標題中的專門功能。 這是否甚至重要? –

+0

@PetarVelev確實很重要。至少一個顯式特化的聲明必須在它所使用的地方可見,否則編譯器會從主模板實例化一個隱式特化(這會產生錯誤)。 – Angew

1

你可以做

template <typename> struct AlwaysFalse : false_type {}; 


template<class T> 
T Foo::get(const std::string&) 
{ 
    static_assert(AlwaysFalse<T>::value, "unsupported data type"); 
} 

因此斷言是模板依賴。

+0

我很想嘗試關閉這個副本:https://stackoverflow.com/questions/30078818/static-assert-dependent-on-non-type-template-parameter-different-behavior-on-gc這與您的答案相矛盾。有什麼想法嗎? – bolov

+0

@bolov:這與我的回答並不矛盾。 'AlwaysFalse ::值** ** **依賴於'T'。我們可能會構造'dummy'類並專用'struct AlwaysFalse :true_type {};'有一個有效的實例化'Foo :: get '。 – Jarod42

+0

嗯..有這樣的引用:「在模板內部,一些結構具有不同的實例到另一個實例的語義,這樣的結構依賴於模板參數。」 – bolov