c++ - constexpr 的可变长度数组错误
问题描述
我有一个带有成员函数的类,它声明了一个大小基于公式的数组。
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
类名。
解决方案
情况很复杂...
首先,一些编译器(请参阅 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()
不涉及您的类的对象,因此您的代码可以编译。
推荐阅读
- mysql - #1136 - 列计数与第 1 行的值计数不匹配,不缺少逗号。值中没有额外的逗号
- node.js - LoopBack 4 - 在 API 资源管理器中添加“授权”按钮
- rest - 在 Bot Framework 中外部 API 调用成功时发送消息
- python - ParseError:格式不正确(无效标记):第 47 行,第 27 列
- c++ - 无法从另一个函数访问指针数组
- angular - RxJS 嵌套订阅
- javascript - 异步 setTimeout 阻止快速处理,直到 res.send 发生
- java - spring 应用程序中的 CORS 策略阻止了来自 Angular 应用程序的请求
- django - 在 Django 中,如何从另一个模板引用一个模板?
- javascript - 将 JQuery 放在 React 组件中的什么位置?