0

テンプレートを使用して単純に見えることをしようとしていますが、それを機能させることができません。このクラスはAVRプロセッサ用にさまざまなシリアルIO実装を実装していますが、問題は一般的なC++の問題です。目標は、コンパイル時に、使いやすさとコードの再利用の向上、およびその再利用による一部の場所でのパフォーマンスの向上のために、テンプレートパラメーターに基づいてオプションを作成することです。

問題は単純ですが、解決策(もしあれば)が見つかりません。Visual Studio 2008を使用して次のコードをコンパイルすると、次のようになります。

error C2039: 't1' : is not a member of 'Interface<T1,0,_C>
error C2039: 't1' : is not a member of 'Interface<T1,1,_C>
error C2039: 't2' : is not a member of 'Interface<T2,0,_C>
error C2039: 't2' : is not a member of 'Interface<T2,1,_C>

**テストコードを説明用のチャンクに分割し、テストケース全体でそれらをすべてまとめました**

これは「一般的な」基本テンプレートです。

enum eType { T1,  T2 };
enum eT1  { T1_I1, T1_I2 };
enum eT2  { T2_I1, T2_I2 };

//This defines the 'global/default' interface that is required
template< eType _T, int _I, typename _C>
struct Interface
{
    bool initialise();
};

このために、_Tパラメーターに基づいてテンプレートを部分的に特殊化し、initialise()などで使用されるメンバー変数を追加します。

//t1 has a new member function which initialise() uses
template< int _I, typename _C>
struct Interface< T1, _I, _C >
{
    bool initialise();
    void t1();
};

//t2 has a new member function which initialise() might uses
template< int _I, typename _C>
struct Interface< T2, _I, _C >
{
    bool initialise();
    void t2();
};

//We can implement a function for T1 type
template< int _I, typename _C>
bool Interface< T1, _I, _C >::initialise()
{ printf( "T1 initialise\n"); return true; }

//We can implement a function for T2 type
template< int _I, typename _C>
bool Interface< T2, _I, _C >::initialise()
{ printf( "T2 initialise\n"); return true; }

//We can implement a function for T1 special function
template< int _I, typename _C>
void Interface< T1, _I, _C >::t1()
{ printf( "T1\n"); }

//We can implement a function for T2 special function
template< int _I, typename _C>
void Interface< T2, _I, _C >::t2()
{ printf( "T2\n"); }

ここで、2番目のテンプレートパラメーター_Iに基づいてt1()およびt2()関数の実装を特殊化する方法を理解することができません。

//################ ISUE BELOW ###################

//ERROR: We can't implement the special function for T1 based on _I specialization
template< typename _C>
void Interface< T1, (int)T1_I1, _C >::t1()
{ printf( "T1_I1 Special function\n"); }

//ERROR: We can't implement the special function for T1 based on _I specialization
template< typename _C>
void Interface< T1, (int)T1_I2, _C >::t1()
{ printf( "T1_I2 Special function\n"); }

//ERROR: We can't implement the special function for T2 based on _I specialization
template< typename _C>
void Interface< T2, (int)T2_I1, _C >::t2()
{ printf( "T2_I1 Special function\n"); }

//ERROR: We can't implement the special function for T2 based on _I specialization
template< typename _C>
void Interface< T2, (int)T2_I2, _C >::t2()
{ printf( "T2_I2 Special function\n"); }

//################ ISUE END ###################

次に、すべてをテストするmain()関数をコンパイルします。

int _tmain(int argc, _TCHAR* argv[])
{
    struct Config {};
    Interface<T1, T1_I1, Config> t1i1;
    Interface<T1, T1_I2, Config> t1i2;
    Interface<T2, T2_I1, Config> t2i1;
    Interface<T2, T2_I2, Config> t2i2;

    t1i1.initialise();
    t1i2.initialise();
    t1i1.t1();
    t1i2.t1();

    t2i1.initialise();
    t2i2.initialise();
    t2i1.t2();
    t2i2.t2();
    return 0;
}

この問題は、コンパイラが元のクラス特殊化の存在を認識せず、t1()またはt2()を持たない非特殊化インターフェイスを使用していることが原因であると思われます。ここで構文が間違っているのはどこですか、それとも私がやろうとしていることを達成するための簡単なハック/回避策がありますか。Serial<UART,Hardware,Config> io解決策が私の目標を達成するという形のタイプをもたらすことができる限り!

4

1 に答える 1

0

すべての部分的なクラスの専門分野を1つずつ詳しく説明する必要があります。例:

template <eType E, int I, typename T> struct Interface;

template <int I, typename T> struct Interface<T1, I, T>
{ 
    void t1() { /* ... */ }
    bool initialize() { /* ... */ }
};

template <typename T> struct Interface<T1, static_cast<int>(T1), T>
{ 
    void t1() { /* ... */ }
    bool initialize() { /* ... */ }
};

必要に応じて、繰り返しを避けるために、いつでもコードを因数分解することができます。例えば:

namespace detail
{
    template <typename T, int I> struct T1Helper
    {
        static bool initialize() { /* ... */ }
    };
}

// ... primary template as above ...

template <int I, typename T> struct Interface<T1, I, T>
{
     void t1() { /* ... */ }
     bool initialize() { return detail::T1Helper<T, I>::initialize(); }
};

// etc.

または、共通コードをミックスインテンプレートに組み込むこともできます。

template <int I, typename T>
struct Interface<T1, I, T> : Mixin<T, I>
{
    void t1() { /* ... */ }
};
于 2013-02-20T23:44:57.700 に答える