I recently came to know that for complex expression(like expressions involving operators) in a require-clause the standard requires the use of parentheses.
But then I wrote the following program where the use of || works without parentheses but the use of == is not allowed. Demo
template<typename T> struct C
{
constexpr static bool b = T{} + 1;
constexpr static bool c = T{} + 1;
};
//template<typename T> requires C<T>::b == C<T>::c void f(); //all compilers reject this
template<typename T> requires C<T>::b || C<T>::c void bar(); //all compilers accepts this
int main()
{
// f<int>(); //fails in all three compilers
bar<int>(); //works in all three compilers
}
I want to know why is the == version not compile but the || version does?
I want to know why is the == version not compile but the || version does?
Because the standard grammar explicitly allows || in a require-clause without parentheses but not == as explained below..
From requires-clause:
requires-clause: requires constraint-logical-or-expression constraint-logical-or-expression: constraint-logical-and-expression constraint-logical-or-expression || constraint-logical-and-expression ^^
As you can see, the use of || is allowed. Basically, the requires has custom behavior for || and &&.
But note ==(and other operators) without parentheses is not allowed as also explained in the old post. For reference, there is also a non-normative note in the standard:
[ Note: The expression in a requires-clause uses a restricted grammar to avoid ambiguities. Parentheses can be used to specify arbitrary expressions in a requires-clause. [ Example:
template<int N> requires N == sizeof new unsigned short int f(); // error: parentheses required around == expression— end example] — end note]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With