2011-01-12 6 views

答えて

1

どちらも部分的な特殊化を必要とします。最初はSFINAEが必要です。関数テンプレートは完全に特殊化できるだけなので、何らかのヘルパーオブジェクトを使用する必要があります。

template <typename T, int P> 
T item(size_t s); 

template < typename T, typename Enable = void > 
struct item_ 
{ 
    template < int P > 
    T apply(size_t s); 
}; 

template < typename T > 
struct item_<T, typename enable_if< is_numeric<T> >::type > 
{ 
    template < int P > 
    static T apply(size_t s) { return static_cast<T>(rand()); } 
}; 

template < > 
struct item_<std::string, void> 
{ 
    template < int P > 
    static std::string apply(size_t s) { return "NSTHEOSUNTH"; } 
}; 

template < typename T, int P > 
T item(size_t s) { return item_<T>::template apply<P>(s); } 

また、タグディスパッチ検討するかもしれない:

struct numeric_tag {}; 
struct string_tag {}; 
struct wtf_tag {}; 

template < typename T, int P > 
T item(size_t s, numeric_tag) { return static_cast<T>(rand()); } 
template < typename T, int P > 
T item(size_t s, string_tag) { return "SNTHEO"; } 
template < typename T, int P > 
T item(size_t s) 
{ 
    item(s, if_ 
      < 
      is_numeric<T> 
      , numeric_tag 
      , typename if_ 
      < 
       is_same< std::string, T > 
      , string_tag 
      , wtf_tag 
      >::type 
      >::type()); 
} 

それとも、タグと一致し、ペアのベクトルを使用して...各最初のテストにそれらを反復処理するためにいくつかのメタ関数クラスをミックス可能性があり(メタファンクションクラス)、2番目のタグ(タグ)を返して実装を選択します。

これについてはたくさんの方法があります。

+0

申し訳ありませんが、私のコンパイラがすべての時間を主張して以来、私はis_numeric を取得できますか... – bua

5

あなたがすることができませんそのような関数テンプレートを特化する。テンプレートの部分的な特殊化は、クラステンプレートに対してのみです。

しかし、boost::enable_ifを使用すると、探している機能テンプレートの部分的な特殊化の種類を「エミュレート」できます。

// Specialization for std::string 
// 
template <int P, typename T> 
T item(size_t, typename boost::enable_if<boost::is_same<T, std::string> >::type* = 0) 
{ 
    .... 
} 

// Specialization for int 
// 
template <int P, typename T> 
T item(size_t, typename boost::enable_if<boost::is_same<T, int> >::type* = 0) 
{ 
    .... 
} 

この方法で、あなたはitem<5, std::string>(10)を呼び出す場合は、最初の関数を呼び出します、そしてあなたがitem<5, int>(10)を呼び出す場合は、第2の機能を呼び出します。

また、Boostを何らかの理由で使用したくない場合は、もちろん部分的に特殊化できるディスパッチャクラステンプレートを作成することもできます。

+0

-1 "テンプレートの特殊化と部分的な特殊化はクラステンプレートのみです。"機能テンプレートは完全に特殊化することができます。 –

+0

@ノア、はい - あなたは間違いなく正しいです。私は答えを改訂しました。 –

+0

-1が表示されます。しかし、まだ私の答えを好む。 –

-4

機能テンプレートは、すべてに特化することはできません。あなたはそれらを過負荷にすることができます、あなたはそれらを専門にすることはできません。彼らは存在していた場合

は、関数テンプレートの一部の特殊化の結合修正、のようなものによって与えられることになります。これらは一意の名前で識別しているので、

template<class T, class U> X f(T,U); 

specialise template<class A, class B> X f(A,B) 
    with template <class K> <K,K*>; 

テンプレートクラスは簡単に専門の仕様を持って、関数のオーバーロード、そうではない。

+3

-1です。 –

+3

ファンクションテンプレートを特殊化することはできますが、部分テンプレート化はできません。 – Timo

関連する問題