【问题标题】:How to statically assert a common property of many classes如何静态断言许多类的共同属性
【发布时间】:2009-05-26 23:47:37
【问题描述】:

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

我怎样才能使用BOOST_STATIC_ASSERT 之类的东西来应用到所有这些

  1. 我只需要在一个地方使用BOOST_STATIC_ASSERT(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 );

【问题讨论】:

  • 为什么你需要断言所有的大小都是 512(或其他一些幻数)?我问是因为这通常会告诉您是否需要重复自己,以及如果您不想重复自己,应该去哪里做这样的测试。例如,如果 512 是高速缓存行的大小,那么您需要将 A、B 和 C 与“完全适合高速缓存行”的一些概念相关联并在某处表达。
  • 原因是因为所有这些类都是相关的,尽管一个共同点是它们的大小要求正好是 512 字节长。那么为什么会有不同的类呢?这是因为 A、B 和 C 表达不同类型的消息。

标签: c++ boost static-assert


【解决方案1】:

这似乎适用于 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 */ };

【讨论】:

  • Nikolai:这样一来,每次实例化 A 类时,它会支付 BOOST_STATIC_ASSERT 成本吗?
  • 每个单独派生的成本是在编译时。这没有运行时成本(假设编译器进行空基优化。)
【解决方案2】:

由于这些类没有关系,我现在看到了这样做的方法,因为您必须明确说明要检查的女巫类型。

执行此操作的唯一 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 的一种可能方法是将所有静态断言放在一个地方。

【讨论】:

    猜你喜欢
    • 2020-05-19
    • 2016-05-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-21
    • 2021-12-16
    相关资源
    最近更新 更多