C++ constexpr 自动成员函数。铛问题?

C++ constexpr auto member function. Clang issue?

 #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{};
 }

上面的代码不会在trunk 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,但不是直接来自 struct?看起来,当我需要 auto return 类型推导时,它失败并声称函数不是 constexpr?

这是预期的吗?我觉得这应该不是问题,如果这是预期的行为,我会感到惊讶。

  1. constexpr 函数可以在编译时和 运行 时调用。
  2. 如果您可以省略 constexpr 并获得适当的普通函数,则带有 constexpr 函数的代码是格式良好的。换句话说,它 必须 编译为 运行 时间函数。
  3. 如果 constexpr 函数的主体无法在编译时计算,它仍然会被编译,但您不能在模板参数等编译时上下文中使用它。
  4. 如果在 constexpr 对象上调用 constexpr 方法,this 被认为是 constexpr。

one 的情况下它是错误的,因为当它在 运行 时被编译为 运行 时,_data[a] 被认为是 运行-时间表达式,因为 a 不是常量表达式,即使 thisthis->_data 是。

two 的情况下它编译得很好,因为它在 运行 时工作正常,并且在编译时 thisconstexpra,因此 this->_data[a]constexpr,一切正常。

如果你在 [dcl.constexpr]/7 中考虑这个语句:

A call to a constexpr function produces the same result as a call to an equivalent non-constexpr function in all respects except that a call to a constexpr function can appear in a constant expression.

考虑非 constexpr 等效函数 A::one()_data[a] 不能用于常量表达式(作为非类型模板参数),因为它会涉及 this 的计算,来自 [expr.const]:

A conditional-expression e is a core constant expression unless the evaluation of e, following the rules of the abstract machine (1.9), would evaluate one of the following expressions:
(2.1) — this (5.1.1), except in a constexpr function or a constexpr constructor that is being evaluated as part of e;

由于非 constexpr 等价物格式错误,constexpr 函数给出相同结果是合理的。

另一方面,two() 是一个结构良好的成员函数,与 constexpr 无关,并且您对 ex.two(3) 的使用作为常量表达式是有效的 - 这就是它编译的原因。