2009-05-26 15 views
0

私は3つのクラスを持っているとしましょう。 sizeof()はそれぞれのクラスがまったく同じであると思います。たとえば512バイトです。多くのクラスの共通のプロパティを静的にアサートする方法

は、どのように私はに適用するBOOST_STATIC_ASSERTのようなものを使用することができ、それらの全てのこのようなこと

    私は1つの場所で BOOST_STATIC_ASSERTを使用する必要が
  1. (DRY原則)
  2. は、コンパイル時に一度だけ評価していません実行時

注:我々は、我々は(など、より多くのクラス、使用の継承を作成する)好きなC++テクニックを使用することができます

私の素朴な溶液は以下の通りである:

class A { ...stuff }; BOOST_STATIC_ASSERT(sizeof(A) == 512); 
class B { ...stuff }; BOOST_STATIC_ASSERT(sizeof(B) == 512); 
class C { ...stuff }; BOOST_STATIC_ASSERT(sizeof(C) == 512); 
+2

なぜ、サイズがすべて512(または他の魔方数)になると主張する必要がありますか?なぜなら、それは自分自身を繰り返す必要があるかどうか、そしてあなたが自分自身を繰り返さないことを望むなら、そのようなテストがどこに行かなければならないかを伝えるからです。 たとえば、512がキャッシュラインのサイズである場合、A、B、Cを「キャッシュラインに正確に適合する」という概念に関連付ける必要があり、それをどこかで表現する必要があります。 – MSN

+0

その理由は、それらのクラスのすべてが関連しているからですが、1つの共通点は、そのサイズがちょうど512バイトの長さである必要があるということです。だからなぜ違うクラス?これは、A、B、およびCが異なるタイプのメッセージを表現するためです。 – sivabudh

答えて

9

これは、GCC 4.0.1で動作し、1.39を後押しするようだ:


template <typename T, size_t S> 
struct enforce_size 
{ 
    enforce_size() 
    { 
     BOOST_STATIC_ASSERT(sizeof(T) == S); 
    } 
}; 

class A: enforce_size<A,512> { /* stuff */ }; 
 
+0

+1:あなたは私より速いです:D – Klaim

+0

エラーメッセージには何らかの作業が必要ですが、 –

+0

ニコライ。 –

1

これらのクラスは関係がないように、私は今ので、これを行う方法を参照してくださいチェックしたい魔女のタイプを明示しなければなりません。

これを実行するDRY方法は、Nikolai N Festissovが提案したものです。私はいくつかのマイナーな変更を加えて同様の例を書いていましたが、グローバルな考え方はboost :: nocopyのようなクラスを作り、子クラスを与えられたサイズにすることです。

template< typename CheckedType, size_t FixedSize > 
class SizeChecked // simple, no inheritance overload 
{ 
public: 
    SizeChecked() 
    { 
     // c++0x or compilers with static_assert() available 
     //static_assert(sizeof(CheckedType) == FixedSize, "Type size check failed!"); 
     BOOST_STATIC_ASSERT(sizeof(CheckedType) == FixedSize); 
    } 

}; 

template< typename CheckedType > 
class Size512 : public SizeChecked< CheckedType, 512 > // simple, no inheritance overload 
{}; 

//////////////////////////////////////////////////////////////////// 

class A : Size512<A> // automatically check 
{ 
}; 


class B : Size512<B> // automatically check 
{ 
    std::array< char, 512 > m_array; 
}; 

class C : SizeChecked< C, 1 > 
{ 
    char m_char; 
}; 

class D : SizeChecked< D, 4 > 
{ 
    short m_k; 
    char m_u; 

}; 


int wmain() 
{ 
    // need instantiation to be checked ! 
    //A a; // will trigger the assertion at compile time 
    B b; // sizeof(B) == 512 : will be fine 
    C c; // sizeof(C) == 1 : will be fine 
    //D d; // will fail because sizeof(short) + sizeof(char) != 4 ! 

} 

注意:継承が緩やかな場合でも、子クラスを明示的にチェックする必要がありますが、チェックは継承されません。

ちなみに、DRYを増やす方法は、すべての静的アサーションを1か所に入れることです。

関連する問題