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
|
// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s
template<typename T> struct X; // expected-note {{'X' is incomplete}}
template<int I> struct Y;
X<X<int>> *x1;
Y<(1 >> 2)> *y1;
Y<1 >> 2> *y2; // FIXME: expected-error{{expected unqualified-id}}
X<X<X<X<X<int>>>>> *x2;
template<> struct X<int> { };
typedef X<int> X_int;
struct Z : X_int { };
void f(const X<int> x) {
(void)reinterpret_cast<X<int>>(x); // expected-error{{reinterpret_cast from}}
(void)reinterpret_cast<X<X<X<int>>>>(x); // expected-error{{reinterpret_cast from}}
X<X<int>> *x1;
}
template<typename T = void> struct X1 { };
X1<X1<>> x1a;
namespace ParameterPackExpansions {
// A template parameter pack that [contains an unexpanded parameter pack] is a
// pack expansion.
template<typename...Ts> struct Outer {
// From [temp.variadic]p4:
// In a template parameter pack that is a pack expansion, the pattern is
// [...the template-parameter...] without the ellipsis.
// Therefore the resulting sequence of parameters is not a parameter pack,
// so is not required to be the last template parameter.
template<Ts ...As, template<Ts> class ...Bs, typename ...Cs> struct Inner {
struct Check : Bs<As>... {
Check(Cs...);
};
};
};
template<int> struct TemplateInt {};
template<char> struct TemplateChar {};
template<int*> struct TemplateIntPtr {};
int x;
Outer<int, char, int*>::
Inner<12345, 'x', &x,
TemplateInt, TemplateChar, TemplateIntPtr,
int*>::
Check check(&x);
template<typename...Ts> struct types;
enum place { _ };
template<place...> struct places {};
template<typename P1, typename P2> struct append_places;
template<place...X1, place...X2>
struct append_places<places<X1...>, places<X2...>> {
typedef places<X1...,X2...> type;
};
template<unsigned N>
struct make_places : append_places<typename make_places<N/2>::type,
typename make_places<N-N/2>::type> {};
template<> struct make_places<0> { typedef places<> type; };
template<> struct make_places<1> { typedef places<_> type; };
template<typename T> struct wrap {
template<place> struct inner { typedef T type; };
};
template<typename T> struct takedrop_impl;
template<place...X> struct takedrop_impl<places<X...>> {
template<template<decltype(X)> class ...Take,
template<place > class ...Drop>
struct inner { // expected-note 2{{declared}}
typedef types<typename Take<_>::type...> take;
typedef types<typename Drop<_>::type...> drop;
};
};
template<unsigned N, typename...Ts> struct take {
using type = typename takedrop_impl<typename make_places<N>::type>::
template inner<wrap<Ts>::template inner...>::take; // expected-error {{too few template arguments}}
};
template<unsigned N, typename...Ts> struct drop {
using type = typename takedrop_impl<typename make_places<N>::type>::
template inner<wrap<Ts>::template inner...>::drop; // expected-error {{too few template arguments}}
};
using T1 = take<3, int, char, double, long>::type; // expected-note {{previous}}
// FIXME: Desguar the types on the RHS in this diagnostic.
// desired-error {{'types<void, void, void, void>' vs 'types<int, char, double, (no argument)>'}}
using T1 = types<void, void, void, void>; // expected-error {{'types<void, void, void, void>' vs 'types<typename inner<_>::type, typename inner<_>::type, typename inner<_>::type, (no argument)>'}}
using D1 = drop<3, int, char, double, long>::type;
using D1 = types<long>;
using T2 = take<4, int, char, double, long>::type; // expected-note {{previous}}
// FIXME: Desguar the types on the RHS in this diagnostic.
// desired-error {{'types<void, void, void, void>' vs 'types<int, char, double, long>'}}
using T2 = types<void, void, void, void>; // expected-error {{'types<void, void, void, void>' vs 'types<typename inner<_>::type, typename inner<_>::type, typename inner<_>::type, typename inner<_>::type>'}}
using T2 = types<int, char, double, long>;
using D2 = drop<4, int, char, double, long>::type;
using D2 = types<>;
using T3 = take<5, int, char, double, long>::type; // expected-note {{in instantiation of}}
using D3 = drop<5, int, char, double, long>::type; // expected-note {{in instantiation of}}
// FIXME: We should accept this code. A parameter pack within a default argument
// in a template template parameter pack is expanded, because the pack is
// implicitly a pack expansion.
template<typename ...Default> struct DefArg {
template<template<typename T = Default> class ...Classes> struct Inner { // expected-error {{default argument contains unexpanded parameter pack}} expected-note {{here}}
Inner(Classes<>...); // expected-error {{too few}}
};
};
template<typename T> struct vector {};
template<typename T> struct list {};
vector<int> vi;
list<char> lc;
DefArg<int, char>::Inner<vector, list> defarg(vi, lc);
// FIXME:
// A template parameter pack that is a pack expansion shall not expand a
// parameter pack declared in the same template-parameter-list.
template<typename...Ts, Ts...Vs> void error(); // desired-error
// This case should not produce an error, because in A's instantiation, Cs is
// not a parameter pack.
template<typename...Ts> void consume(Ts...);
template<typename...Ts> struct A {
template<template<typename, Ts = 0> class ...Cs, Cs<Ts> ...Vs> struct B { // ok
B() {
consume([]{
int arr[Vs]; // expected-error {{negative size}}
}...);
}
};
};
template<typename, int> using Int = int;
template<typename, short> using Char = char;
A<int, short>::B<Int, Char, -1, 'x'> b; // expected-note {{here}}
}
namespace PR9023 {
template<typename ...T> struct A {
template<template<T> class ...> struct B {
};
};
template<int> struct C { };
template<long> struct D { };
int main() {
A<int, long>::B<C, D> e;
}
}
namespace std_examples {
template <class... Types> class Tuple;
template <class T, int... Dims> struct multi_array;
template <class... T> struct value_holder {
template<T... Values> struct apply { };
};
template <class... T, T... Values> struct static_array; // expected-error {{must be the last}}
int n;
value_holder<int, char, int*>::apply<12345, 'x', &n> test;
}
|