使用VS2015的Constexpr查找表

时间:2016-10-26 07:10:06

标签: c++ visual-studio-2015 constexpr lookup-tables

我正在寻找如何制作查找表并找到this简单而优雅的答案。

我不想删除帖子,所以我想我会提出一个新问题。在VS2015中尝试编译该答案时,我收到以下错误:

template<int N>
struct Table
{
  constexpr Table() : values()
  {
    // C3538 auto must always deduce the same type 
    // C3250 i declaration is not allowed in constexpr body
    // C3249 illegal statement for sub-expression 'constexpr' function
    for (auto i = 0; i < N; ++i)
    {
        values[i][0] = i;
        values[i][1] = i * i * i;
    }
  }
  int values[N][2];
};

int main(){
  // defctor does not produce a constant value 
  constexpr auto a = Table<1000>();
  return 0;
}

我尝试用std::array替换C样式数组,因为我认为这可能有助于迭代过程。我还检查了一些在线编译器上的代码,它在那里工作,但在VS中没有。

问题是什么,如何在没有模板膨胀代码的情况下复制解决方案?

1 个答案:

答案 0 :(得分:3)

如上面的评论所示,MSVC 2015并不支持C ++ 14 constexpr,但它确实支持许多其他C ++ 14功能,所以你可以这样做:

#include <cstddef>
#include <utility>

template<int N> struct Table
{
   constexpr Table() : Table(std::make_index_sequence<N>{}) { }
   int values[N][2];
private:
   template<std::size_t... Is> constexpr Table(std::index_sequence<Is...>)
      : values{{Is, Is * Is * Is}...} { }
};

int main()
{
   constexpr auto a = Table<100>{};
   static_assert(a.values[77][0] == 77 && a.values[77][1] == 77 * 77 * 77, "oops");
}

IntelliSense仍然抱怨a的初始化,但这是一个错误。 MSVC接受代码(在C ++ 14模式下也是Clang和GCC)。

请注意,在原始代码中使用NTable<1000>)的较大值会产生警告:

warning C4503: 'Table<1000>::Table': decorated name length exceeded, name was truncated

据我在阅读the docs时可以看出,在这种情况下可以安全地忽略警告。