“requires” ignores a field is not static

我们两清 提交于 2021-02-08 19:47:11

问题


Consider the following code:

#include <iostream>

constexpr int fun(int const&) { return 5; }
struct T { int x; };

int main() {
  std::cout << fun(T::x) << std::endl;                   // Line A
  std::cout << requires { fun(T::x); } << std::endl;     // Line B
}

If I only comment Line B, then the code cannot be compiled (as expected, since x is not static in T). But when I only comment Line A, the code compiles just fine with both Clang 11.0.0 and GCC 10.2.0 (both output 1). What it is that I am missing about requires? shouldn't it return false?


回答1:


A requires expression is one big list of unevaluated operands.

[expr.prim.req]

2 A requires-expression is a prvalue of type bool whose value is described below. Expressions appearing within a requirement-body are unevaluated operands.

And a qualified-id naming a non-static data member always could appear in an unevaluated operand.

[expr.prim.id]

2 An id-expression that denotes a non-static data member or non-static member function of a class can only be used:

  • as part of a class member access in which the object expression refers to the member's class or a class derived from that class, or

  • to form a pointer to member ([expr.unary.op]), or

  • if that id-expression denotes a non-static data member and it appears in an unevaluated operand. [ Example:

struct S {
  int m;
};
int i = sizeof(S::m);           // OK
int j = sizeof(S::m + 42);      // OK

— end example ]

The unevaluated operand where T::x may appear can be any expression. So even pre-C++20 you could for example write

decltype(fun(T::x)) i{};


来源:https://stackoverflow.com/questions/64798455/requires-ignores-a-field-is-not-static

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!