xref: /llvm-project/clang/test/CXX/temp/temp.param/p11-0x.cpp (revision 651c73ce784cb551c99ef306e74990c0fe57b533)
19ca5c425SRichard Smith // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
20018cdc1SDouglas Gregor 
33f1b5d07SRichard Smith // If a template-parameter of a class template or alias template has a default
43f1b5d07SRichard Smith // template-argument, each subsequent template-parameter shall either have a
53f1b5d07SRichard Smith // default template-argument supplied or be a template parameter pack.
60018cdc1SDouglas Gregor template<typename> struct vector;
70018cdc1SDouglas Gregor 
83f1b5d07SRichard Smith template<typename T = int, typename> struct X3t; // expected-error{{template parameter missing a default argument}} expected-note{{previous default template argument defined here}}
93f1b5d07SRichard Smith template<typename T = int, typename> using A3t = int; // expected-error{{template parameter missing a default argument}} expected-note{{previous default template argument defined here}}
103f1b5d07SRichard Smith template<int V = 0, int> struct X3nt; // expected-error{{template parameter missing a default argument}} expected-note{{previous default template argument defined here}}
113f1b5d07SRichard Smith template<int V = 0, int> using A3nt = int; // expected-error{{template parameter missing a default argument}} expected-note{{previous default template argument defined here}}
123f1b5d07SRichard Smith template<template<class> class M = vector, template<class> class> struct X3tt; // expected-error{{template parameter missing a default argument}} expected-note{{previous default template argument defined here}}
133f1b5d07SRichard Smith template<template<class> class M = vector, template<class> class> using A3tt = int; // expected-error{{template parameter missing a default argument}} expected-note{{previous default template argument defined here}}
143f1b5d07SRichard Smith 
150018cdc1SDouglas Gregor template<typename T = int, typename ...Types> struct X2t;
163f1b5d07SRichard Smith template<typename T = int, typename ...Types> using A2t = X2t<T, Types...>;
170018cdc1SDouglas Gregor template<int V = 0, int ...Values> struct X2nt;
183f1b5d07SRichard Smith template<int V = 0, int ...Values> using A2nt = X2nt<V, Values...>;
190018cdc1SDouglas Gregor template<template<class> class M = vector, template<class> class... Metas>
200018cdc1SDouglas Gregor   struct X2tt;
213f1b5d07SRichard Smith template<template<class> class M = vector, template<class> class... Metas>
223f1b5d07SRichard Smith   using A2tt = X2tt<M, Metas...>;
230018cdc1SDouglas Gregor 
243f1b5d07SRichard Smith // If a template-parameter of a primary class template or alias template is a
253f1b5d07SRichard Smith // template parameter pack, it shall be the last template-parameter.
260018cdc1SDouglas Gregor template<typename ...Types, // expected-error{{template parameter pack must be the last template parameter}}
27*651c73ceSDavid Blaikie          int After, int After2>
280018cdc1SDouglas Gregor struct X0t;
29*651c73ceSDavid Blaikie X0t<int> pr9789();
303f1b5d07SRichard Smith template<typename ...Types, // expected-error{{template parameter pack must be the last template parameter}}
313f1b5d07SRichard Smith          int After>
323f1b5d07SRichard Smith using A0t = int;
330018cdc1SDouglas Gregor 
340018cdc1SDouglas Gregor template<int ...Values, // expected-error{{template parameter pack must be the last template parameter}}
350018cdc1SDouglas Gregor          int After>
360018cdc1SDouglas Gregor struct X0nt;
373f1b5d07SRichard Smith template<int ...Values, // expected-error{{template parameter pack must be the last template parameter}}
383f1b5d07SRichard Smith          int After>
393f1b5d07SRichard Smith using A0nt = int;
400018cdc1SDouglas Gregor 
410018cdc1SDouglas Gregor template<template<typename> class ...Templates, // expected-error{{template parameter pack must be the last template parameter}}
420018cdc1SDouglas Gregor          int After>
430018cdc1SDouglas Gregor struct X0tt;
443f1b5d07SRichard Smith template<template<typename> class ...Templates, // expected-error{{template parameter pack must be the last template parameter}}
453f1b5d07SRichard Smith          int After>
463f1b5d07SRichard Smith using A0tt = int;
470018cdc1SDouglas Gregor 
480018cdc1SDouglas Gregor // [ Note: These are not requirements for function templates or class
490018cdc1SDouglas Gregor // template partial specializations because template arguments can be
500018cdc1SDouglas Gregor // deduced (14.8.2). -- end note]
510018cdc1SDouglas Gregor template<typename... Types> struct X1t;
520018cdc1SDouglas Gregor template<typename ...Types, typename T> struct X1t<T, Types...> { };
530018cdc1SDouglas Gregor 
540018cdc1SDouglas Gregor template<int... Values> struct X1nt;
550018cdc1SDouglas Gregor template<int ...Values, int V> struct X1nt<V, Values...> { };
560018cdc1SDouglas Gregor 
57eb29d18eSDouglas Gregor template<template<int> class... Meta> struct X1tt;
58eb29d18eSDouglas Gregor template<template<int> class... Meta, template<int> class M>
59eb29d18eSDouglas Gregor   struct X1tt<M, Meta...> { };
600018cdc1SDouglas Gregor 
610018cdc1SDouglas Gregor template<typename ...Types, typename T>
620018cdc1SDouglas Gregor void f1t(X1t<T, Types...>);
630018cdc1SDouglas Gregor 
640018cdc1SDouglas Gregor template<int ...Values, int V>
650018cdc1SDouglas Gregor void f1nt(X1nt<V, Values...>);
660018cdc1SDouglas Gregor 
67eb29d18eSDouglas Gregor template<template<int> class... Meta, template<int> class M>
68eb29d18eSDouglas Gregor void f1tt(X1tt<M, Meta...>);
698b481d8aSDouglas Gregor 
708b481d8aSDouglas Gregor namespace DefaultTemplateArgsInFunction {
f0(U)718b481d8aSDouglas Gregor   template<typename T = int, typename U>  T &f0(U) { T *x = 0; return *x; }
728b481d8aSDouglas Gregor 
test_f0()738b481d8aSDouglas Gregor   void test_f0() {
748b481d8aSDouglas Gregor     int &ir0 = f0(3.14159);
758b481d8aSDouglas Gregor     int &ir1 = f0<int>(3.14159);
768b481d8aSDouglas Gregor     float &fr0 = f0<float>(3.14159);
778b481d8aSDouglas Gregor   }
788b481d8aSDouglas Gregor 
798b481d8aSDouglas Gregor   template<> int &f0(int*);
808b481d8aSDouglas Gregor   template int &f0(double&);
818b481d8aSDouglas Gregor }
82