【问题标题】:Variable length array error with constexprconstexpr 的可变长度数组错误
【发布时间】:2020-09-01 10:30:25
【问题描述】:

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

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和类名。

【问题讨论】:

  • n 来自哪里?
  • 通过一些小的语法修复,它可以正常运行:repl.it/repls/WanLavishComputergames
  • @BillLynch - 编译和运行良好,但不是标准 C++;如果添加“-pedantic”,则会收到警告“警告:可变长度数组是 C99 功能”。

标签: c++ arrays c++11 template-meta-programming constexpr


【解决方案1】:
  • 类模板必须有名称。
  • 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)];
   }
};

【讨论】:

  • 嗯...我不认为应该有效。如果添加hoge&lt;2&gt; h; h.func()(可能将func() 声明为public:)并使用clang++ 或g++ 使用-ansi -padantic 进行编译,则会收到“警告:可变长度数组是C99”(clang++)或“警告:ISO C++ 禁止变长数组”(g++)。如果在func() 中添加一行constexpr int s = lookup(SIZE);,则会出现错误。
  • 嗯……抱歉……在我之前的评论中……-pedantic,而不是-padantic
【解决方案2】:

这很复杂……

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

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

因为它们支持接受“可变长度数组”功能的 C99 扩展。

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

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

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

    double array[s];
}

如果lookup() 是非静态方法,则无法编译

考虑一下

 lookup(SIZE);

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

我的意思是...lookup() 的使用涉及您的类的一个对象。

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

假设你有一个非constexpr 对象:从它调用func() 你强加了这个

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

在编译时进行评估。

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

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

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

【讨论】:

  • 感谢您筛选我的错别字,看看我想问什么!
猜你喜欢
  • 2012-05-04
  • 1970-01-01
  • 1970-01-01
  • 2020-11-20
  • 2020-10-26
  • 2014-07-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多