Should static member function b be visible to the requires-clause of the default constructor of s? What does the C++20 standard say about the legality of the provided example?
template<auto...>
struct s {
s() requires (s::b()) = default; // clang nope, gcc ok, msvc ok
static constexpr bool b()
{ return true; }
};
static_assert((s<>{}, true));
The error message from Clang:
<source>:3:22: error: no member named 'b' in 's<...>'
3 | s() requires (s::b()) = default;
| ~~~^
<source>:7:15: error: static assertion expression is not an integral constant
expression
7 | static_assert((s<>{}, true));
| ^~~~~~~~~~~~~
<source>:7:16: note: non-constexpr constructor 's' cannot be used in a constant
expression
7 | static_assert((s<>{}, true));
| ^
<source>:3:5: note: declared here
3 | s() requires (s::b()) = default;
| ^
The behavior(ill-formed) of the program can be understood using expr.const#5 which states:
(emphasis mine)
And since at the point of the invocation of
s::b(), the staticconstexprfunction is undefined, the expressions::b()is not a constant expression at that point. Combine this with the fact that the context where the invocation is used is not a complete class context, we get the mentioned error.Thus, the program is ill-formed.