1 // RUN: %clang_cc1 -std=c++2a -x c++ -verify %s 2 3 template<typename T> 4 constexpr bool is_ptr_v = false; 5 6 template<typename T> 7 constexpr bool is_ptr_v<T*> = true; 8 9 template<typename T, typename U> 10 constexpr bool is_same_v = false; 11 12 template<typename T> 13 constexpr bool is_same_v<T, T> = true; 14 15 template<typename T> requires is_ptr_v<T> // expected-note {{because 'is_ptr_v<int>' evaluated to false}} 16 // expected-note@-1{{because 'is_ptr_v<char>' evaluated to false}} 17 auto dereference(T t) { // expected-note {{candidate template ignored: constraints not satisfied [with T = int]}} 18 // expected-note@-1{{candidate template ignored: constraints not satisfied [with T = char]}} 19 return *t; 20 } 21 22 static_assert(is_same_v<decltype(dereference<int*>(nullptr)), int>); 23 static_assert(is_same_v<decltype(dereference(2)), int>); // expected-error {{no matching function for call to 'dereference'}} 24 static_assert(is_same_v<decltype(dereference<char>('a')), char>); // expected-error {{no matching function for call to 'dereference'}} 25 26 template<typename T> requires (T{} + T{}) // expected-note {{because substituted constraint expression is ill-formed: invalid operands to binary expression ('A' and 'A')}} 27 auto foo(T t) { // expected-note {{candidate template ignored: constraints not satisfied [with T = A]}} 28 return t + t; 29 } 30 31 32 template<typename T> requires (!((T{} - T{}) && (T{} + T{})) || false) 33 // expected-note@-1{{because substituted constraint expression is ill-formed: invalid operands to binary expression ('A' and 'A')}} 34 // expected-note@-2{{and 'false' evaluated to false}} 35 auto bar(T t) { // expected-note {{candidate template ignored: constraints not satisfied [with T = A]}} 36 return t + t; 37 } 38 39 struct A { }; 40 41 static_assert(foo(A{})); // expected-error {{no matching function for call to 'foo'}} 42 static_assert(bar(A{})); // expected-error {{no matching function for call to 'bar'}}