Как статически утверждать общее свойство многих классов - PullRequest
0 голосов
/ 27 мая 2009

Допустим, у меня есть 3 класса. Я ожидаю, что sizeof () каждого класса будет одинаковым - скажем, 512 байт.

Как я могу использовать что-то вроде BOOST_STATIC_ASSERT, чтобы применить ко всем из них так, чтобы

  1. Мне нужно использовать BOOST_STATIC_ASSERT только в одном месте (принцип СУХОЙ)
  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 ]

9 голосов
/ 27 мая 2009

Это похоже на работу с gcc 4.0.1 и 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 */ };

1 голос
/ 27 мая 2009

Поскольку эти классы не имеют отношения, я теперь вижу способ сделать это, потому что вы должны четко указывать типы ведьм, которые вы хотите проверить.

Единственный СУХОЙ способ обеспечить это - то, что предложил Николай Н. Фестисов. Я писал подобный пример с некоторыми незначительными изменениями, но глобальная идея состоит в том, чтобы создать класс, подобный 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 !

}

Осторожно: если вы потеряете наследование, вам все равно придется явно проверить дочерние классы, проверка не наследуется!

Кстати, возможный способ быть более СУХИМЫМ - это поместить все ваши статические утверждения в одном месте.

...