C++ constexpr自动成员函数.Clang问题?

pat*_*pat 3 c++ constexpr auto c++11 c++14

 #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{};
 }
Run Code Online (Sandbox Code Playgroud)

上面的代码不会在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.
Run Code Online (Sandbox Code Playgroud)

显然,功能标记constexpr,如果你注释掉one()成员,一切编译罚款,所以我们显然能够创建integral_constantex从,但不直接struct?看来,当我需要auto返回类型演绎时,它失败并声称功能不是constexpr

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

Bar*_*rry 6

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

constexpr函数的调用产生在所有方面调用等效非constexpr函数相同的结果,除了对函数的调用可以出现在常量表达式中.constexpr

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

条件表达式e是核心常量表达式,除非根据抽象机器(1.9)的规则评估e将评估以下表达式之一:
(2.1) - this(5.1.1),除了constexpr函数或constexpr作为e的一部分进行评估的构造函数;

由于非constexpr等效形式是不正确的,因此该constexpr函数给出相同的结果是合理的.

另一方面,two()无论如何都是一个格式良好的成员函数,constexpr并且你的使用ex.two(3)作为常量表达式是有效的 - 这就是它编译的原因.