【问题标题】:Check sizes are the same when compiling编译时检查大小相同
【发布时间】:2011-11-16 17:02:51
【问题描述】:

我有一个字典和一个数组,它们在程序中都不会改变大小,但通常可以在编译前进行扩展。键的数量和数组长度应始终保持相同的大小。有没有办法在编译时检查这一点,因为添加键很容易但不能添加到数组中,反之亦然?

【问题讨论】:

  • 应该显示一些代码,至少是那些声明..
  • 一些代码会很有帮助。
  • 我不知道 dictionary 类型,在 C++ 中 array 永远无法更改大小。你能澄清一下你在做什么吗?
  • 目前还不完全清楚您要做什么。 countof()sizeof(array)/sizeof(array[0]) 不是一个选项吗?否则我可能误解了......
  • 是否使用相同的 const 值来指定数组中的元素数和键数不是选项?

标签: c++ compilation c-preprocessor


【解决方案1】:

有一些方法可以检查编译时常量。在 C++11 中,它与 static_assert 结合在一起,但也可以使用模板。

例如给出:

enum Key {
  K_Zero,
  K_One,
  K_Two,
  K_NUMBER_ELEMENTS
};

static char const Dictionary[] = { ... };

你会用 C++11 来做:

static_assert(K_NUMBER_ELEMENTS == ARRAY_SIZE(Dictionary),
              "Keys / Dictionary mismatch");

其中ARRAY_SIZE定义为:

template <typename T, unsigned N>
char (&ComputeArraySize(T (&)[N]))[N];

#define ARRAY_SIZE(Array) sizeof(ComputeArraySize(Array))

如果你还在 C++03 中(如果你不知道版本可能就是这种情况),那么你应该更聪明一点,将 static_assert 替换为:

template <unsigned M, unsigned N> struct mp_equal;

template <unsigned N> struct mp_equal<N,N> {};

namespace {
  mp_equal<K_NUMBER_ELEMENTS, ARRAY_SIZE(Dictionary)> 
    AssertKeysAndDictionarySizeMatch = {};
}

如果它们不匹配会触发编译时错误。

【讨论】:

  • +1。但您实际上并不需要定义ComputeArraySize()。只有声明就足够了。而且我认为,回报不应该是ArraySize&lt;N&gt;。应该是这样的:typename ArraySize&lt;N&gt;::type 其中ArraySize 定义为template &lt;unsigned N&gt; struct ArraySize { typedef char (&amp;type)[N]; };
  • 这很好,但除非我们知道“字典”是什么意思,否则它不是答案。
  • @Nawaz:实际上,这是作弊。通常,函数不能返回数组。所以我只是将数组包装到一个类中,并祈祷编译器不会在不需要时突然引入奇怪的填充。但是你是对的,这个定义没有意义。
  • @MichaelPrice:我假设 OP 在要求编译时检查时知道他在说什么。这是信仰的飞跃……
  • @MatthieuM。 : 这就是我使用数组引用的 typedef 的原因。你也可以这样做,它根本不需要任何结构:ideone.com/9wVc4
【解决方案2】:

假设通过字典您的意思是 mapunordered_map 在编译时没有直接的方法。您可以在 main 中运行 assert 或者您可以强制映射始终从对数组初始化,然后 static_assert 对数组的长度与您的主数组相同。

【讨论】:

    猜你喜欢
    • 2015-07-31
    • 1970-01-01
    • 2013-10-24
    • 2020-01-07
    • 1970-01-01
    • 1970-01-01
    • 2013-10-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多