【问题标题】:How to precompute array of values?如何预先计算值数组?
【发布时间】:2008-11-07 16:22:57
【问题描述】:

有没有办法根据模板预先计算一组值?在下面的示例中,如果可能的话,我希望 'powers_of_2' 数组在编译时计算 256 个值,而无需键入所有值。

#include <iostream>
using namespace std;

template <int X, char Y>
struct power {
   enum { value = X * power<X,Y-1>::value };
};

template <int X>
struct power<X,1> {
   enum { value = X };
};

template <int X>
struct power<X,0> {
   enum { value = 1 };
};

int _tmain(int argc, _TCHAR* argv[])
{
   int powers_of_2[] = { power<2,0>::value, power<2,1>::value, ..., power<2,255>::value };
   cout << powers_of_2[1] << endl;
   return 0;
}

【问题讨论】:

  • 实际上,现在我再次查看您的问题(除了溢出问题),您似乎已经有了答案。 ???

标签: c++ templates


【解决方案1】:

除非您打算使用大整数包,否则整数类型会在 2^32(或 2^64,视情况而定)溢出,但要回答您真正的问题,请查看template metaprogramming 上的这篇维基百科文章。

【讨论】:

  • 我修改了我的问题,所以 Y 现在的类型是 char 而不是 int。
  • 如果 Y 不是无符号字符,看起来不是,那么 Y 的范围是 -128 到 127。即使 Y 是无符号的,范围也只是从 0 到 255(所以你错过了256)。即使这样 X 仍然是一个整数,它会在 2^32 或 2^64 溢出,具体取决于机器和编译器。
  • 模板元编程不足以完成此类任务。即使宏不支持递归,它们也是实现语句重复的唯一可行方法。
【解决方案2】:

这正是宏的用处......

【讨论】:

    【解决方案3】:

    保持值 2^255 需要 32 个字节。这不能保存在 int 中;你需要一个 char 数组

    typedef unsigned char BYTE32[32];
    BYTE32 powers_of_2[256] =
    {
      {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
      {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
      {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2},
      {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4},
      {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8},
      {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16},
      {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32},
      {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64},
      {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128},
      {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0},
      {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0},
    // :
    // :
      {32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
      {64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
      {128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
    };
    

    【讨论】:

      【解决方案4】:

      在这种情况下,我所做的是编写一个小程序,该程序生成并写入 C++ 源代码中的数组初始化文件,然后 #include 该文件。这种技术简单有效。

      【讨论】:

        【解决方案5】:

        您可以轻松编写一个小脚本,使用您喜欢的脚本语言为您预填​​充数组。根据您使用的编译器和预处理器,您还应该能够将其作为宏来执行。

        【讨论】:

          【解决方案6】:

          我同意 Lokkju。仅通过模板元编程来初始化数组是不可能的,在这种情况下宏非常有用。甚至 Boost 库也使用宏来实现重复语句。

          此处提供了有用的宏示例:http://awgn.antifork.org/codes++/macro_template.h

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2014-05-26
            • 1970-01-01
            • 1970-01-01
            • 2017-05-20
            • 2016-03-11
            • 1970-01-01
            • 2012-08-12
            • 1970-01-01
            相关资源
            最近更新 更多