How to statically assert a common property of many classes

Let's say I have 3 classes. I expect sizeof () each class to be exactly the same - say 512 bytes.

How can I use something like BOOST_STATIC_ASSERT

to apply to all of them so that

  • I BOOST_STATIC_ASSERT

    only need to use in one place (DRY principle)
  • Evaluated once at compile time, not runtime

Note: we can use whatever C ++ methods we want (create more classes, use inheritance, etc.)

My naive solution is presented below:

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 );

      

0


a source to share


2 answers


This seems to work with gcc 4.0.1 and boost 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 */ };

      

+9


a source


Since these classes are unrelated, I can see now a way to do this, because you need to be explicit about the types of witches you want to test.

The only DRY way to ensure this is what Nikolai N. Festissov suggested. I wrote a similar example with some minor changes, but the global idea is to create a boost :: nocopy class that will force the child class to be the specified size.

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 !

}

      



Beware: if you lose inheritance, you must still provide explicit checking for child classes, checking is not inherited!

By the way, a possible way to be more DRY would be to put all your static statements in just one place.

+1


a source







All Articles