2011-12-17 4 views
7

VC++ 10で、次の例はエラーC2027で失敗します: "未定義型 'X'の使用。しかし、g ++ 4.6はそれをうまくコンパイルします。CRTPを使用しているときにテンプレート引数のサイズを取得する方法は?

template<class T> 
class C 
{ 
    static const size_t size = sizeof(T); 
}; 

class X : public C<X> { }; 

だからどちらが正しいですか?そして、これをメインストリームのコンパイラで動作させるにはどうしたらよいですか?

VC++はCのメンバー関数内でsizeof(T)を使用することができますが、これは大したことではありません。ちょっとした迷惑な長い型定義を繰り返す必要があります。

EDIT: 私は、私が本当にやりたかったことは、このように、一定のコンパイル時間とサイズを使用していたので、私の例が悪かった実現:

template<size_t size> class C2 { }; 

template<class T> 
class C 
{ 
    typedef C2<sizeof(T)> A; 
}; 

class X : public C<X> { }; 

両方のコンパイラは、私はこれを拒否それはおそらく不可能だと仮定しますが、私はまだ関数の内部のsizeofを使用することができると言った。私は、すべての関数の中でtypedefを繰り返す必要はないと思っていました。

template<size_t size> class C2 { }; 

template<class T> 
class C 
{ 
    void foo() { typedef C2<sizeof(T)> A; } 
}; 

class X : public C<X> { }; 

答えて

6

静的メンバは、型Tが定義されているため、クラス自体で初期化することができず、まだ完了していません。それは罰金コンパイルする必要があり

template<class T> 
class C 
{ 
    static const size_t size; 
}; 

template<typename T> 
const size_t C<T>::size = sizeof(T); //initialization of the static member 

ただし、として、クラスの外にそれを初期化することができhttp://ideone.com/6sNgN

+1

1は同じものを投稿するちょうど約ました。 –

+0

これは問題ではないと思います。なぜなら、整数コンパイル時定数は通常、クラス内で初期化できるからです。私はそれを回避策として受け入れるかもしれない。 – Timo

+0

@Timo:それはまさに問題です。その時点で、静的メンバは解析され、初期化しようとしています*、型 'T'はまだ完了していません。 – Nawaz

関連する問題