我有带有 constexpr 方法的 constexpr 对象构造函数。
// My SparseArray implementation
#include <cstdint>
#include <iostream>
#include <utility>
template<typename T, uint64_t size>
class SparseArray
{
public:
using ElementType = T;
template<typename... Args>
constexpr SparseArray(Args&&... args)
: values{args...} {
std::cout << "Args ctor." << '\n';
}
template<uint8_t Index>
constexpr ElementType get() const {
// some logic
return T();
}
constexpr auto someMethod() {
get<0>(); // <--------- works fine
auto seq = std::integer_sequence<ElementType, 0>{}; // <--------- works fine
auto seq2 = std::integer_sequence<ElementType, get<0>()>{}; // <-- error
}
ElementType values[size];
};
int main ()
{
SparseArray<int, 3> array(1, 2, 3);
array.someMethod();
return 0 ;
}
但我确实需要在这样的编译时上下文中使用方法。 我要在编译时对两个 constexpr 对象求和,因此我需要使用 get 方法获取两者的数据。
=======已编辑=====
@chris 回答后,我明白我错过了一件事。 实际上 get 方法是这样的:
template<uint8_t Index>
constexpr ElementType get() const {
if(/*some logic*/)
return values[/*some logic*/];
else
return T();
}
因此,代码处理对象的数据成员。
最佳答案
constexpr
函数必须在编译时和运行时可用。您正在调用一个非静态成员函数,因此无论类对象在编译时是否已知,它都需要工作。如果您需要在编译时知道该对象,则该函数在运行时不再有效。
解决此问题的最简单方法是使用不依赖于未使用的类对象的函数:
template<uint8_t Index>
static constexpr ElementType get() {
// some logic
return T();
}
如果这不是一个选项,因为您正在使用类对象,那么您需要确保该对象是 constexpr 才能使用它:
constexpr SparseArray<int, 3> array(1, 2, 3);
auto seq2 = std::integer_sequence<int, array.get<0>()>{};
无论您在何处使用 get
,结果可用作编译时值的唯一方法是所有参数(包括对象)都是编译时值。
EWG 已接受 constexpr!
强制对函数进行编译时评估,但在与 constexpr SparseArray
对象一起使用之前,它不会使您的原始示例编译。
关于c++ - 错误 : 'this' is not a constant expression,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51152012/