2017-03-25 3 views
1

私の理解では、javaテンプレート定義の拡張と同様に、次のクラスのintとstringの2つの型だけを制限したいと思います。vC++のテンプレートを使用して型を制限する

template<typename T> 
typename std::enable_if<std::is_same<T,int>::value || std::is_same<T,string>::value>::type 
class ExchangeSort 
{ 
public: 
    void bubbleSort(T buffer[], int s); 
    void print(T buffer[], int s); 
    void bubbleSort(const vector<T>& vec); 
}; 

しかし、私はExchangeSortが定義されていない上記の行のためのエラーを取得しています

ExchangeSort<int>* sortArray = new ExchangeSort<int>; 

以下のようにインスタンス化しています。何が問題ですか ?

答えて

1

SFINAEを使用して、関数のオーバーロードまたはテンプレートの特殊化を条件付きで無効にすることができます。クラステンプレートをオーバーロードすることができないので、クラステンプレートを無効にするためにそれを使用しようとするのは意味がありません。あなたは、静的なアサーションを使用したほうが良いでしょう:

template<typename T> 
class ExchangeSort 
{ 
    static_assert(std::is_same<T,int>::value || std::is_same<T,string>::value, "ExchangeSort requires int or string"); 
public: 
    // The rest as before 

は、あなたが取得したエラーについては、コードが構文上の意味がありませんでした。 enable_ifは、タイプが予想される場所にのみ表示されます。関数では、それはしばしばあなたが書いたものと構文的に似ている戻り値の型をラップするために使用されます。しかし、クラスでは、 templateとクラス定義の間に型がありません。

0

ここでラインのさらに下の専門分野を追加する可能性を可能にする別の方法です:

#include <type_traits> 
#include <vector> 
#include <string> 

// 
// Step 1 : polyfill missing c++17 concepts 
// 
namespace notstd { 

    template<class...> struct disjunction : std::false_type { }; 
    template<class B1> struct disjunction<B1> : B1 { }; 
    template<class B1, class... Bn> 
    struct disjunction<B1, Bn...> 
      : std::conditional_t<bool(B1::value), B1, disjunction<Bn...>> { }; 
} 

// 
// Step 2 : create a test to see if a type is in a list 
// 
namespace detail { 

    template<class T, class...Us> 
    struct is_one_of : notstd::disjunction< std::is_same<T, Us>... > {}; 
} 

template<class T, class...Us> 
static constexpr auto IsOneOf = detail::is_one_of<T, Us...>::value; 


// 
// Step 3 : declare the default specialisation, but don't define it 
// 

template<class T, typename Enable = void> 
struct ExchangeSort; 

// 
// Step 4 : define the specialisations we want 
// 
template<typename T> 
class ExchangeSort<T, std::enable_if_t<IsOneOf<T, int, std::string>>> 
{ 
public: 
    void bubbleSort(T buffer[], int s); 
    void print(T buffer[], int s); 
    void bubbleSort(const std::vector<T>& vec); 
}; 


// 
// Test 
// 

int main() 
{ 

    auto esi = ExchangeSort<int>(); 
    auto ess = ExchangeSort<std::string>(); 

// won't compile  
// auto esd = ExchangeSort<double>(); 

} 
関連する問題