cplusplus / CWG

Core Working Group
23 stars 7 forks source link

[temp.pre] requires-clause grammar doesn't allow for use of operator with template id #513

Closed ranaanoop closed 3 months ago

ranaanoop commented 3 months ago

Full name of submitter: Anoop Rana

Reference (section label): [temp.pre]

Link to reflector thread (if any): https://stackoverflow.com/questions/78155107/requires-compile-with-msvc-but-rejected-by-gcc

Issue description:

The !std::is_enum_v<T> without the parentheses in the below program is ill-formed as per the grammar rules. We see implementation divergence.

#include <type_traits>

template<typename T> requires !std::is_enum_v<T>  //invalid per grammar rules
void foo(T)
{
}

template<typename T> requires std::is_enum_v<T>  //valid per grammar rules
void bar(T)
{
} 

I don't see any reason why !std::is_enum_v<T> is disallowed but std::is_enum_v<T> is allowed. Note that all compilers accept the program if we remove the ! from std::is_enum_v<T>. Demo. That is, I think !std::is_enum_v<T> should also be allowed.

t3nsor commented 3 months ago

Isn't this a feature request?

ranaanoop commented 3 months ago

Isn't this a feature request?

Looks more like an oversight to me. I can write a proposal to EWG etc if thats where this should be submitted.

jensmaurer commented 3 months ago

I don't think there is a question what the standard says in this situation; the grammar in [temp.pre] is pretty obvious.

Also, the grammar as we have it correctly maps to the decomposition yielding atomic constraints. For example, !x is an atomic constraint by itself.

From a design perspective, negated constraints should be rare (and are expensive to implement), so I'm not seeing an urgent need for change.

Extension requests go to EWG via paper, please.

AlanVoore commented 3 months ago

Looking at this comment, it seems that it does make sense to allow omitting parentheses for other operators also.

Note c++ allows omitting parentheses for || and && but not for any other operator.

jensmaurer commented 3 months ago

Note c++ allows omitting parentheses for || and && but not for any other operator.

Yes, because stuff connected via || and && is dissected into atomic constraints. Not so for any other operator.

Any changes in this area need a paper to EWG with rationale and analysis of the resulting grammar ambiguities, in particular since contracts are arriving soon.