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 的对象,因此您的代码可以编译.
我有一个带有成员函数的 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 的对象,因此您的代码可以编译.