#include <utility>
struct A {
constexpr auto one(int a) {
return std::integral_constant<int, _data[a]>{};
}
constexpr int two(int a) const {
return _data[a];
}
int _data[10];
};
int main() {
constexpr auto ex = A{{1,2,3,4,5,6,7,8,9,10}};
std::integral_constant<int, ex.two(3)> b{};
}
以上代码在最新版本的Clang编译器中无法通过编译。错误出现在one()
成员函数中,错误信息如下:
cc.cpp:57:44: note: implicit use of 'this' pointer is only allowed
within the evaluation of a call to a 'constexpr' member function.
显然,该函数被标记为
constexpr
,如果您注释掉one()
成员,一切都能顺利编译。因此,我们显然可以从ex
创建integral_constant
,但是不能直接从struct
中创建吗?当我需要auto
返回类型推导时,它似乎失败并声称该函数不是constexpr
?这是否合理?我觉得这不应该是问题,如果这是预期的行为,我会感到惊讶。
_data[a]
不是A::one
内的常量表达式。请注意,constexpr
函数仍然可以在运行时调用,例如,如果您提供的参数只在运行时才知道。 - dyp_data[a]
都不是常量表达式。但是,constexpr 函数可以由非常量表达式组成。规则是:在需要常量表达式的上下文中,不能评估非常量表达式(包括 constexpr 函数的部分)。此外,必须有一种方式可以在需要常量表达式的上下文中合法地调用constexpr
函数。 - dypconstexpr
是一个限定符,其行为取决于调用站点。因此,two
知道A
是constexpr
,并且do
是this->data[a]
。有趣的部分是为什么它认为one
是不合法的。 - polkovnikov.phtwo
函数不知道该实例已被声明为constexpr
。请考虑使用A a {rand()}; a.two(0)
。这是完全合法的,但函数调用表达式a.two(0)
不能成为常量表达式。 - dypa.two(0)
,但你正在一个需要常量表达式的上下文中使用它。正如我所说:在这个例子中,a.two(0)
是合法的,但它本身不是一个常量表达式,也不能在常量表达式中求值。 - dyp