我有带有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回答之后,我了解到我错过了一件事。 实际上,获取方法如下:
template<uint8_t Index>
constexpr ElementType get() const {
if(/*some logic*/)
return values[/*some logic*/];
else
return T();
}
因此,代码处理对象的数据成员。
答案 0 :(得分:1)
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
对象一起使用时,它才能使您的原始示例编译。