summaryrefslogtreecommitdiffstats
path: root/test/SemaTemplate/default-arguments.cpp
blob: 6391369aa5c470ece2245470d6f5dd69d609607f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
// RUN: %clang_cc1 -fsyntax-only -verify %s
template<typename T, int N = 2> struct X; // expected-note{{template is declared here}}

X<int, 1> *x1;
X<int> *x2;

X<> *x3; // expected-error{{too few template arguments for class template 'X'}}

template<typename U = float, int M> struct X;

X<> *x4;

template<typename T = int> struct Z { };
template struct Z<>;

// PR4362
template<class T> struct a { };
template<> struct a<int> { static const bool v = true; };

template<class T, bool = a<T>::v> struct p { }; // expected-error {{no member named 'v'}}

template struct p<bool>; // expected-note {{in instantiation of default argument for 'p<bool>' required here}}
template struct p<int>;

// PR5187
template<typename T, typename U>
struct A;

template<typename T, typename U = T>
struct A;

template<typename T, typename U>
struct A {
  void f(A<T>);
};

template<typename T>
struct B { };

template<>
struct B<void> {
  typedef B<void*> type;
};

// Nested default arguments for template parameters.
template<typename T> struct X1 { };

template<typename T>
struct X2 {
  template<typename U = typename X1<T>::type> // expected-error{{no type named}}
  struct Inner1 { };
  
  template<T Value = X1<T>::value> // expected-error{{no member named 'value'}}
  struct NonType1 { };
  
  template<T Value>
  struct Inner2 { };
  
  template<typename U>
  struct Inner3 {
    template<typename X = T, typename V = U>
    struct VeryInner { };
    
    template<T Value1 = sizeof(T), T Value2 = sizeof(U), 
             T Value3 = Value1 + Value2>
    struct NonType2 { };
  };
};

X2<int> x2i;
X2<int>::Inner1<float> x2iif;

X2<int>::Inner1<> x2bad; // expected-note{{instantiation of default argument}}

X2<int>::NonType1<'a'> x2_nontype1;
X2<int>::NonType1<> x2_nontype1_bad; // expected-note{{instantiation of default argument}}

// Check multi-level substitution into template type arguments
X2<int>::Inner3<float>::VeryInner<> vi;
X2<char>::Inner3<int>::NonType2<> x2_deep_nontype;

template<typename T, typename U>
struct is_same { static const bool value = false; };

template<typename T>
struct is_same<T, T> { static const bool value = true; };

int array1[is_same<__typeof__(vi), 
               X2<int>::Inner3<float>::VeryInner<int, float> >::value? 1 : -1];

int array2[is_same<__typeof(x2_deep_nontype),
                   X2<char>::Inner3<int>::NonType2<sizeof(char), sizeof(int), 
                                    sizeof(char)+sizeof(int)> >::value? 1 : -1];

// Template template parameter defaults
template<template<typename T> class X = X2> struct X3 { };
int array3[is_same<X3<>, X3<X2> >::value? 1 : -1];

struct add_pointer {
  template<typename T>
  struct apply {
    typedef T* type;
  };
};

template<typename T, template<typename> class X = T::template apply>
  struct X4;
int array4[is_same<X4<add_pointer>, 
                   X4<add_pointer, add_pointer::apply> >::value? 1 : -1];

template<int> struct X5 {}; // expected-note{{has a different type 'int'}}
template<long> struct X5b {};
template<typename T, 
         template<T> class B = X5> // expected-error{{template template argument has different}} \
                                   // expected-note{{previous non-type template parameter}}
  struct X6 {};

X6<int> x6a;
X6<long> x6b; // expected-note{{while checking a default template argument}}
X6<long, X5b> x6c;


template<template<class> class X = B<int> > struct X7; // expected-error{{must be a class template}}

namespace PR9643 {
  template<typename T> class allocator {};
  template<typename T, typename U = allocator<T> > class vector {};

  template<template<typename U, typename = allocator<U> > class container,
           typename DT>
  container<DT> initializer(const DT& d) {
    return container<DT>();
  }

  void f() {
    vector<int, allocator<int> > v = initializer<vector>(5);
  }
}