reference, declarationdefinition
definition → references, declarations, derived classes, virtual overrides
reference to multiple definitions → definitions
unreferenced
    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
  139
  140
  141
  142
  143
  144
  145
  146
  147
  148
  149
  150
  151
  152
  153
  154
  155
  156
  157
  158
  159
  160
  161
  162
  163
  164
  165
  166
  167
  168
  169
  170
  171
  172
  173
  174
  175
  176
  177
  178
  179
  180
  181
  182
  183
  184
  185
  186
  187
  188
  189
  190
  191
  192
  193
  194
  195
  196
  197
  198
  199
  200
  201
  202
  203
  204
  205
  206
  207
  208
  209
  210
  211
  212
  213
  214
  215
  216
  217
  218
  219
  220
  221
  222
  223
  224
  225
  226
  227
  228
  229
  230
  231
// RUN: %clang_cc1 -fsyntax-only -verify %s
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %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 'type' in 'X1<int>'}} \
                                              // expected-error{{no type named 'type' in 'X1<char>'}}
  struct Inner1 { }; // expected-note{{template is declared here}}
  
  template<T Value = X1<T>::value> // expected-error{{no member named 'value' in 'X1<int>'}} \
                                   // expected-error{{no member named 'value' in 'X1<char>'}}
  struct NonType1 { }; // expected-note{{template is declared here}}
  
  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; // expected-note{{in instantiation of template class 'X2<int>' requested here}}
X2<int>::Inner1<float> x2iif;

X2<int>::Inner1<> x2bad; // expected-error{{too few template arguments for class template 'Inner1'}}

X2<int>::NonType1<'a'> x2_nontype1;
X2<int>::NonType1<> x2_nontype1_bad; // expected-error{{too few template arguments for class template 'NonType1'}}

// Check multi-level substitution into template type arguments
X2<int>::Inner3<float>::VeryInner<> vi;
X2<char>::Inner3<int>::NonType2<> x2_deep_nontype; // expected-note{{in instantiation of template class 'X2<char>' requested here}}

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);
  }
}

namespace PR16288 {
  template<typename X>
  struct S {
    template<typename T = int, typename U>
#if __cplusplus <= 199711L // C++03 or earlier modes
    // expected-warning@-2 {{default template arguments for a function template are a C++11 extension}}
#endif
    void f();
  };
  template<typename X>
  template<typename T, typename U>
  void S<X>::f() {}
}

namespace DR1635 {
  template <class T> struct X {
    template <class U = typename T::type> static void f(int) {} // expected-error {{type 'int' cannot be used prior to '::' because it has no members}}
#if __cplusplus <= 199711L // C++03 or earlier modes
    // expected-warning@-2 {{default template arguments for a function template are a C++11 extension}}
#endif
    static void f(...) {}
  };

  int g() { X<int>::f(0); } // expected-note {{in instantiation of template class 'DR1635::X<int>' requested here}}
}

namespace NondefDecls {
  template<typename T> void f1() {
    int g1(int defarg = T::error);  // expected-error{{type 'int' cannot be used prior to '::' because it has no members}}
  }
  template void f1<int>();  // expected-note{{in instantiation of function template specialization 'NondefDecls::f1<int>' requested here}}
}

template <typename T>
struct C {
  C(T t = ); // expected-error {{expected expression}}
};
C<int> obj;

namespace PR26134 {
// Make sure when substituting default template arguments we do it in the current context.
template<class T, bool Val = T::value>
struct X {};

template<bool B> struct Y {
  void f() { X<Y> xy; }
  static const bool value = B;
};

namespace ns1 {
template<class T0>
struct X {
  template<bool B = T0::value> struct XInner { static const bool value = B; };
};
template<bool B> struct S { static const bool value = B; };
#if __cplusplus > 199711L
template<bool B> struct Y {
  static constexpr bool f() { return typename X<S<B>>::template XInner<>{}.value; }
  static_assert(f() == B, "");
};
Y<true> y;
Y<false> y2;
#endif

} // end ns1
} // end ns PR26134

namespace friends {
  namespace ns {
    template<typename> struct A {
      template<typename> friend void f();
      template<typename> friend struct X;
    };
    template<typename = int> void f(); // expected-warning 0-1{{extension}}
    template<typename = int> struct X;
    A<int> a;
  }
  namespace ns {
    void g() { f(); }
    X<int> *p;
  }
}

namespace unevaluated {
  int a;
  template<int = 0> int f(int = a); // expected-warning 0-1{{extension}}
  int k = sizeof(f());
}