[
Note 2: 
A logical negation expression (
[expr.unary.op]) is an atomic constraint;
the negation operator is not treated as a logical operation on constraints
.Furthermore, if substitution to determine
whether an atomic constraint is satisfied (
[temp.constr.atomic])
encounters a substitution failure, the constraint is not satisfied,
regardless of the presence of a negation operator
.[
Example 2: 
template <class T> concept sad = false;
template <class T> int f1(T) requires (!sad<T>);
template <class T> int f1(T) requires (!sad<T>) && true;
int i1 = f1(42);        
                        
template <class T> concept not_sad = !sad<T>;
template <class T> int f2(T) requires not_sad<T>;
template <class T> int f2(T) requires not_sad<T> && true;
int i2 = f2(42);        
template <class T> int f3(T) requires (!sad<typename T::type>);
int i3 = f3(42);        
template <class T> concept sad_nested_type = sad<typename T::type>;
template <class T> int f4(T) requires (!sad_nested_type<T>);
int i4 = f4(42);        
 
Here,
requires (!sad<typename T::type>) requires
that there is a nested 
type that is not 
sad,
whereas
requires (!sad_nested_type<T>) requires
that there is no 
sad nested 
type. — 
end example]
 — 
end note]