2011-11-02 37 views
4

是否可以有條件地隱藏或禁用功能,使用編譯時間常數的模板類?禁用/隱藏功能的基礎上編譯時模板常數

想象以下類:

template<size_t M, size_t N> 
class MyClassT 
{ 
    // I only want this function available if M == N, otherwise it is illegal to call 
    static MyClassT<M, N> SomeFunc() 
    { 
     ... 
    } 
} 


MyClassT<2,2>::SomeFunc(); // Fine 
MyClassT<3,2>::SomeFunc(); // Shouldn't even compile 

回答

7

使用部分特,和繼承:

// Factor common code in a base class 
template <size_t n, size_t m> 
class MyClassTBase 
{ 
    // Put here the methods which must appear 
    // in MyClassT independantly of n, m 
}; 

// General case: no extra methods 
template <size_t n, size_t m> 
class MyClassT : MyClassTBase<n, m> 
{}; 

// Special case: one extra method (you can add more here) 
template <size_t n> 
class MyClassT<n, n> : MyClassTBase<n, n> 
{ 
    static MyClassT<n, n> SomeFunc() 
    { 
     ... 
    } 
}; 

另一種選擇是使用SFINAE:std::enable_if或其變體:

template <size_t n, size_t m> 
class MyClassT 
{ 
    template <typename EnableIf = char> 
    static MyClassT<n, m> SomeFunc(EnableIf (*)[n == m] = 0) 
    { 
     ... 
    } 
}; 

更詳細的選擇(但如果你不知道SFINAE和p ointer到陣列)是

template <size_t n, size_t m> 
class MyClassT 
{ 
    template <typename Dummy = char> 
    static MyClassT<n, m> 
    SomeFunc(typename std::enable_if<n == m, Dummy>::type * = 0) 
    { 
     ... 
    } 
}; 

一般來說,我更喜歡SFINAE接近其中存在一個或兩個成員函數來啓用或禁用。只要它比這更復雜,我更喜歡部分專業化技術。

編輯:由於沒有模板函數,SFINAE代碼是錯誤的。糾正。

4

理想的方式提供專業化是使用模板特。您可以將所有基本功能的基類:

template< size_t M, size_t N > 
class basic_class{ ... }; 

template< size_t M, size_t N > 
class my_class : basic_class< M, N > { ... }; 


template< size_t M > 
class my_class< M, M > : basic_class< M, N > { ... }; 

或者,你可以添加一個虛擬模板參數和使用enable_if

template< typename Dummy = int > 
typename std::enable_if< M == N, my_class >::type some_func(Dummy* = 0);