constexpr 的可变长度数组错误

Variable length array error with constexpr

我有一个带有成员函数的 class,它声明一个数组,其大小基于公式。

template <int SIZE>
class Example{
   constexpr int lookup(const int n) const
   {
      return n * n + n;
   }
   inline void func()
   {
       double array[lookup(SIZE)];
   }
};

这给了我 vla 错误。我认为它应该有效,因为 SIZE 在编译时解析,查找是 constexpr。我知道以下会起作用:

template <int SIZE>
class Example{

   inline void func()
   {
       constexpr int sz = SIZE * SIZE + SIZE;
       double array[sz];
   }
};

我想我只是想弄清楚为什么

编辑 很抱歉打字错误,我只是想写一个更小的例子,结果缺少 n 和 class 名称。

  • Class 模板必须有名称。
  • n 未在 lookup 中声明。

这应该像 C++11 一样工作:

template <int SIZE>
class hoge { // add hoge
   constexpr int lookup(const int n) const // add n
   {
      return n * n + n;
   }
   inline void func()
   {
       double array[lookup(SIZE)];
   }
};

这很复杂...

首先,某些编译器(参见 MikeCAT 答案和 Bill Lynch 链接示例)可以编译以下代码(如果您给 class 命名并正确 lookup() 命名 n 参数)

inline void func()
{
    double array[lookup(SIZE)];
}

因为他们支持接受 "variable length array" 功能的 C99 扩展。

但是这个扩展不是标准的 C++。

您可以验证此修改 func() 如下(几乎等效,在标准 C++ 中)

inline void func()
{
    constexpr int s = lookup(SIZE);

    double array[s];
}

如果 lookup() 是非静态方法

,则无法编译

考虑一下

 lookup(SIZE);

的缩写形式
 this->lookup(SIZE);

我的意思是... lookup() 的使用涉及到您的 class 的对象。

问题是您的 func() 方法可用于 constexpr 和非 constexpr 对象。

假设您有一个非 constexpr 对象:从中调用 func() 您强加

constexpr int s = this->lookup(SIZE);

在编译时计算。

即:您强制要求 this 指针(因此对象本身)在编译时可用。

这对于 运行 时间创建的对象来说显然是不可能的,因此您的代码无法编译。

如果将 lookup() 声明为 static 方法则不同:这样,调用 lookup() 不涉及 class 的对象,因此您的代码可以编译.