2014-01-15 53 views
5

專業函數模板我基本上是有std::integral_constant,包括變量的模擬版本,我想專門從Base<T>派生這些類的函數模板,就像這樣:爲模板派生

template<class T> struct Base{ 
    typedef T type; 
    T t; 
}; 

template<class T> struct A : Base<T>{ 
    static constexpr T value = 1; 
}; 
template<class T> struct B : Base<T>{ 
    static constexpr T value = 2; 
}; 

struct Unrelated{}; 

// etc. 

template<class T> void foo(T t){ 
    //I would like to specialize foo for A and B and have a version for other types 
} 


int main(){ 
    foo(A<float>());//do something special based on value fields of A and B 
    foo(B<float>()); 
    foo(Unrelated()); //do some default behavior 
} 

這裏有主要問題:

  • 我不能包括value爲模板,我期待T = doublefloat,或其他一些非整數類型(否則我只是延長std::integral_constant
  • 我不能用乾淨的std::is_base我會做std::is_base<Base<T::type>,T>
  • foo(Base<T>&)不會讓我看到value,我不想不得不求助於虛擬value()函數(或反射)。
  • 很顯然,我想避免每個派生類都專門化foo。

我認爲答案在於使用is_base,但無論如何嘗試使用它,我都無法使其工作。有沒有更簡單的方法我失蹤?

+0

當然,你有一個或兩個錯字。 'template struct A:Base {'應該是'template struct A:Base {'。這是你的全部問題嗎? –

+0

+1清楚地表達了第一個*你正在嘗試做什麼,然後*如何*你試圖做到這一點,並最終問*你應該怎麼做,你應該做你想做的事情。 –

+0

另外,閱讀[this](http://www.gotw.ca/publications/mill17.htm) –

回答

1

下面應該工作:

template<typename,typename = void> 
struct IsBase 
    : std::false_type {}; 

template<typename T> 
struct IsBase<T, typename std::enable_if< 
        std::is_base_of<Base<typename T::type>,T>::value 
       >::type> 
    : std::true_type {}; 

template<class T> 
typename std::enable_if<IsBase<T>::value>::type foo(T t){ 
    // use T::value 
} 

template<class T> 
typename std::enable_if<!IsBase<T>::value>::type foo(T t){ 
    // general case 
} 

Live example

+0

即使它沒有'typename T :: type.'的失敗問題,我也不會工作,如果我做了'foo ()'(至少在g ++ 4.6中)。就像我說的,我做了幾乎是一樣的東西,但沒有能夠讓它完全按照我的意願工作。 – user783920

+1

@ user783920'foo ()''不提供參數,但'foo'(按照您的定義)需要參數't'。如果您沒有正確描述您的問題,我認爲我無法提供幫助。 –

+0

我已經刪除了模板,但現在它可以工作。我想我忘了保存什麼,對不起。 – user783920