0

これに似た質問がすでにスタックオーバーフローにいくつかありますが、私が持っている質問に直接答えているように見えるものは何もありません。転載の場合はご容赦ください。

テンプレート化されたクラス (2 つのテンプレート パラメーターを持つ) のいくつかのメソッドを、それらのメソッドの部分的なテンプレート特殊化でオーバーロードしたいと思います。正しい構文を理解できず、不可能だと考え始めています。ここに投稿して、確認できるかどうかを確認したいと思いました。

従うコード例:

template <typename T, typename U>
class Test
{
public:
    void Set( T t, U u ); 

    T m_T;
    U m_U;
};

// Fully templated method that should be used most of the time
template <typename T, typename U>
inline void Test<T,U>::Set( T t, U u )
{
    m_T=t;
    m_U=u;
}

// Partial specialisation that should only be used when U is a float.
// This generates compile errors
template <typename T>
inline void Test<T,float>::Set( T t, float u )
{
    m_T=t;
    m_U=u+0.5f;
}


int _tmain(int argc, _TCHAR* argv[])
{
    Test<int, int> testOne;    
    int a = 1;
    testOne.Set( a, a );

    Test<int, float> testTwo;    
    float f = 1.f;
    testTwo.Set( a, f );
}

クラス全体の部分的な特殊化を書くことができることは知っていますが、それはちょっとひどいです。このようなことは可能ですか?

(私はVS2008を使用しています)編集:これはコンパイルエラーエラーですC2244: 'Test::Set':関数定義を既存の宣言に一致させることができません

ありがとう :)

4

3 に答える 3

6

クラス テンプレート自体の部分的な特殊化を定義しないと、メンバー関数を部分的に特殊化することはできません。テンプレートの部分的な特殊化はまだテンプレートであることに注意してください。したがって、コンパイラがTest<T, float>を参照すると、クラス テンプレートの部分的な特殊化が期待されます。

--

$14.5.4.3/1 from the C++ Standard (2003) によると、

クラス テンプレートの部分的特殊化のメンバーのテンプレート パラメーター リストは、クラス テンプレートの部分的特殊化のテンプレート パラメーター リストと一致する必要があります。クラス テンプレートの部分的特殊化のメンバーのテンプレート引数リストは、クラス テンプレートの部分的特殊化のテンプレート引数リストと一致する必要があります。クラス テンプレートの特殊化は、別個のテンプレートです。クラス テンプレートの部分的な特殊化のメンバーは、プライマリ テンプレートのメンバーとは無関係です。定義が必要な方法で使用されるクラス テンプレートの部分的な特殊化メンバーを定義する必要があります。プライマリ テンプレートのメンバーの定義は、クラス テンプレートの部分的な特殊化のメンバーの定義として使用されることはありません。クラス テンプレートの部分的な特殊化のメンバーの明示的な特殊化は、プライマリ テンプレートの明示的な特殊化と同じ方法で宣言されます。

次に、標準自体がこの例を示しています。

// primary template
template<class T, int I> struct A {
void f();
};
template<class T, int I> void A<T,I>::f() { }

// class template partial specialization
template<class T> struct A<T,2> {
void f();
void g();
void h();
};
// member of class template partial specialization
template<class T> void A<T,2>::g() { }

例とともに標準からの引用があなたの質問にうまく答えることを願っています.

于 2011-03-05T19:07:46.387 に答える
1

あなたがスケッチしている特定の問題は簡単です:

template< class T >
inline T foo( T const& v ) { return v; }

template<>
float foo( float const& v ) { return v+0.5; }

次に、実装fooから呼び出しますTest::Set

完全な汎用性が必要な場合は、同様にヘルパー クラスを静的ヘルパー メンバー関数と共に使用し、そのヘルパー クラスを部分的に特殊化します。

乾杯 & hth.,

于 2011-03-05T20:42:37.210 に答える
0

コードに追加の関数、メソッド、またはクラスを導入したくない場合は、部分的な特殊化の問題に対する別の解決策もあります。

#include <type_traits>

template <typename T1, typename T2>
class C
{
    void f(T1 t1);
}

template <typename T1, typename T2>
void C<T1, T2>::f(T1 t1)
{
    if (std::is_same<T2, float>::value)
    // Do sth
    else
    // Do sth
}
于 2013-01-02T12:40:56.617 に答える