2015-09-08 111 views
4

假設我有一組類從單個超之傳承:調用模板方法只允許子類作爲參數

class S{ ... }; 

class C1 : public S{ ... }; 
class C2 : public S{ ... }; 

然後,假設我有一個模板方法:

template<class T> void foo(T* instance); 

我想靜態檢查foo從未被稱爲提供超類的實例,但僅被稱爲提供(具體)子類中的一個(例如明確地調用foo<C1>(x)

這可能嗎?

回答

10

首先,我們可以寫一個特點,以檢查是否TS得出,但不S

template <class Base, class Derived> 
using is_strict_base = 
    std::integral_constant<bool, 
     std::is_base_of<Base,Derived>::value && 
     !std::is_same<Base,typename std::remove_cv<Derived>::type>::value>; 

您可以使用std::enable_if使用這個特質:

template<class T> 
typename std::enable_if<is_strict_base<S,T>::value>::type 
foo(T* instance) 
{} 

用C++ 14你可以用std::enable_if_t使它更漂亮一些:

template<class T> 
std::enable_if_t<is_strict_base<S,T>::value> 
foo(T* instance) 
{} 

另一種選擇是使用static_assert

template<class T> 
void foo(T* instance) 
{ 
    static_assert(is_strict_base<S,T>::value, 
        "T must be derived from S, but not S"); 
} 

這給你一個更好的錯誤,但我個人認爲一個函數的類型約束的聲明屬於。

相關問題