1 // RUN: %clang_cc1 -std=c++11 -verify %s
2 // RUN: %clang_cc1 -std=c++2a -verify %s
4 struct Q
{ typedef int type
; };
6 // "The substitution occurs in all types and expressions that are used in [...]
7 // template parameter declarations." In particular, we must substitute into the
8 // type of a parameter pack that is not a pack expansion, even if we know the
9 // corresponding argument pack is empty.
10 template<typename T
, typename
T::type
...> void a(T
);
12 int &a_disabled
= a(0);
13 int &a_enabled
= a(Q()); // expected-error {{cannot bind to a temporary of type 'void'}}
15 template<typename T
, template<typename
T::type
> class ...X
> void b(T
);
17 int &b_disabled
= b(0);
18 int &b_enabled
= b(Q()); // expected-error {{cannot bind to a temporary of type 'void'}}
20 template<typename T
, template<typename
T::type
...> class ...X
> void c(T
);
22 int &c_disabled
= c(0);
23 int &c_enabled
= c(Q()); // expected-error {{cannot bind to a temporary of type 'void'}}
25 // The substitution proceeds in lexical order and stops when a condition that
26 // causes deduction to fail is encountered.
27 #if __cplusplus > 201702L
28 namespace reversed_operator_substitution_order
{
33 Cat
operator<=>(Y
, X
);
34 bool operator<(int, Cat
);
36 template<typename T
> struct indirect_sizeof
{
37 static_assert(sizeof(T
) != 0);
38 static const auto value
= sizeof(T
);
41 // We should substitute into the construction of the X object before the
42 // construction of the Y object, so this is a SFINAE case rather than a
43 // hard error. This requires substitution to proceed in lexical order
44 // despite the prior rewrite to
45 // 0 < (Y(...) <=> X(...))
46 template<typename T
> float &f(
48 X(sizeof(T
)) < Y(indirect_sizeof
<T
>::value
)
51 template<typename T
> int &f(...);
53 int &r
= no_adl::f
<void>(true);
54 float &s
= no_adl::f
<int>(true);