C++ 如何静态断言多个类的公共属性

C++ 如何静态断言多个类的公共属性,c++,boost,static-assert,C++,Boost,Static Assert,假设我有三节课。我希望每个类的sizeof()都完全相同——比如512字节 如何使用类似于BOOST\u STATIC\u ASSERT的方法来应用于所有这些应用程序 我只需要在一个地方使用BOOST\u STATIC\u ASSERT(干式原理) 在编译时计算一次,而不是在运行时 注:我们可以使用任何我们想要的C++技术(创建更多的类,使用继承等) 我的简单解决方案如下所示: class A { ...stuff }; BOOST_STATIC_ASSERT( sizeof(A) == 512

假设我有三节课。我希望每个类的sizeof()都完全相同——比如512字节

如何使用类似于
BOOST\u STATIC\u ASSERT
的方法来应用于所有这些应用程序

  • 我只需要在一个地方使用
    BOOST\u STATIC\u ASSERT
    (干式原理)
  • 在编译时计算一次,而不是在运行时
  • 注:我们可以使用任何我们想要的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 );
    

    这似乎适用于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 */ };
    
    
    样板
    结构强制大小
    {
    强制执行大小()
    {
    BOOST_STATIC_ASSERT(sizeof(T)=S);
    }
    };
    A类:强制执行大小{/*stuff*/};
    

    由于那个些类并没有关系,我现在看到了实现这一点的方法,因为你们必须明确你们想要检查的巫婆类型

    执行这一点的唯一干法是尼古拉·费斯蒂索夫(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 !
    
    }
    
    template
    类SizeChecked//简单,无继承重载
    {
    公众:
    SizeChecked()
    {
    //c++0x或具有静态断言()的编译器可用
    //静态断言(sizeof(CheckedType)=FixedSize,“类型大小检查失败!”);
    BOOST\u STATIC\u ASSERT(sizeof(CheckedType)=FixedSize);
    }
    };
    模板
    类Size512:public SizeChecked//简单,无继承重载
    {}; 
    ////////////////////////////////////////////////////////////////////
    A类:Size512//自动检查
    {
    };
    B类:Size512//自动检查
    {
    std::arraym_数组;
    };
    C类:尺寸小于C,1>
    {
    charmu char;
    };
    D类:尺寸小于D,4>
    {
    短文;
    查穆;
    };
    int wmain()
    {
    //需要检查实例化!
    //A;//将在编译时触发断言
    B;//sizeof(B)==512:可以
    cc;//sizeof(C)==1:可以
    //D D;//将失败,因为sizeof(short)+sizeof(char)!=4!
    }
    
    注意:如果您丢失了继承,您仍然必须对子类提供显式检查,该检查不是继承的


    顺便说一句,一种可能的方法是将所有静态断言放在一个地方。

    为什么需要断言大小都是512(或其他一些神奇的数字)?我这样问是因为这通常会告诉你是否需要重复你自己,如果你不想重复你自己,那么这样的测试应该去哪里。例如,如果512是缓存线的大小,那么您需要将a、B和C与“恰好适合缓存线”的概念相关联,并将其表达在某个地方。原因是所有这些类都是相关的,尽管一个共同点是它们的大小要求正好为512字节长。那为什么不同的班级呢?这是因为A、B和C表示不同类型的消息。Nikolai:通过这种方式,每次实例化类A时,它是否会支付BOOST_STATIC_ASSERT的成本?每个单独的派生的成本都是在编译时产生的。这没有运行时成本(假设编译器执行空基优化)