これらのクラスには関係がないため、チェックしたい魔女のタイプを明示する必要があるため、これを行う方法がわかりました。
これを強制する唯一の 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 か所だけに配置することです。