https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96821
--- Comment #7 from Patrick Palka <ppalka at gcc dot gnu.org> --- (In reply to Daniil Dudkin from comment #5) > (In reply to Patrick Palka from comment #4) > > GCC's behaviour is correct, I think. Since the concept constant_expression > > doesn't use its template parameter, the normal form of foo's associated > > constraint is just 'true (with an empty parameter mapping)', so the > > satisfaction value of with_value_constant<T> for any T is trivially true and > > independent of T. > > > No, I don't think that GCC behaviour is correct. > > http://eel.is/c++draft/temp.constr#atomic-3 > > > If substitution results in an invalid type or expression, the constraint is > > not satisfied. 'Substitution' here refers to substitution into the atomic constraints of a constraint-expression, not into the constraint-expression directly. Atomic constraints are formed via constraint normalization. In the case of with_value_constant<T>, normalization of this constraint-expression yields the single atomic constraint 'true (with an empty parameter mapping)' as per [temp.constr.atomic]/1 and [temp.constr.normal]. The substitution 'T=WithNonConstant' into this atomic constraint will never fail, because the atomic constraint doesn't depend on any template parameters. > > The substitution with_value_constant<WithNotConstant::value> results in an > invalid expression because WithNotConstant::value is not a constant > expression, so it cannot be used as a non-type template argument. That means > with_value_constant<WithNotConstant::value> should be false regardless how > with_value_constant is defined. As mentioned before, you need to make the concept constant_expression depend on its template parameter so that normalization doesn't throw away the 'T::value' template argument inside the definition of with_value_constant. (In reply to Alexander Zaitsev from comment #6) > Any updates on the issue? Such behaviour is strange too since Clang and MSVC > have a different opinion from GCC for the code. I think GCC is behaving correctly here.