1 // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s 2 3 // Metafunction to extract the Nth type from a set of types. 4 template<unsigned N, typename ...Types> struct get_nth_type; 5 6 template<unsigned N, typename Head, typename ...Tail> 7 struct get_nth_type<N, Head, Tail...> : get_nth_type<N-1, Tail...> { }; 8 9 template<typename Head, typename ...Tail> 10 struct get_nth_type<0, Head, Tail...> { 11 typedef Head type; 12 }; 13 14 // Placeholder type when get_nth_type fails. 15 struct no_type {}; 16 17 template<unsigned N> 18 struct get_nth_type<N> { 19 typedef no_type type; 20 }; 21 22 template<typename T, typename U> struct pair { }; 23 template<typename T, typename U> pair<T, U> make_pair(T, U); 24 25 // For a function parameter pack that occurs at the end of the 26 // parameter-declaration-list, the type A of each remaining argument 27 // of the call is compared with the type P of the declarator-id of the 28 // function parameter pack. 29 template<typename ...Args> 30 typename get_nth_type<0, Args...>::type first_arg(Args...); 31 32 template<typename ...Args> 33 typename get_nth_type<1, Args...>::type second_arg(Args...); 34 35 void test_simple_deduction(int *ip, float *fp, double *dp) { 36 int *ip1 = first_arg(ip); 37 int *ip2 = first_arg(ip, fp); 38 int *ip3 = first_arg(ip, fp, dp); 39 no_type nt1 = first_arg(); 40 } 41 42 template<typename ...Args> 43 typename get_nth_type<0, Args...>::type first_arg_ref(Args&...); 44 45 template<typename ...Args> 46 typename get_nth_type<1, Args...>::type second_arg_ref(Args&...); 47 48 void test_simple_ref_deduction(int *ip, float *fp, double *dp) { 49 int *ip1 = first_arg_ref(ip); 50 int *ip2 = first_arg_ref(ip, fp); 51 int *ip3 = first_arg_ref(ip, fp, dp); 52 no_type nt1 = first_arg_ref(); 53 } 54 55 56 // FIXME: Use the template parameter names in this diagnostic. 57 template<typename ...Args1, typename ...Args2> 58 typename get_nth_type<0, Args1...>::type first_arg_pair(pair<Args1, Args2>...); // expected-note{{candidate template ignored: could not match 'pair<type-parameter-0-0, type-parameter-0-1>' against 'int'}} 59 60 template<typename ...Args1, typename ...Args2> 61 typename get_nth_type<1, Args1...>::type second_arg_pair(pair<Args1, Args2>...); 62 63 void test_pair_deduction(int *ip, float *fp, double *dp) { 64 int *ip1 = first_arg_pair(make_pair(ip, 17)); 65 int *ip2 = first_arg_pair(make_pair(ip, 17), make_pair(fp, 17)); 66 int *ip3 = first_arg_pair(make_pair(ip, 17), make_pair(fp, 17), 67 make_pair(dp, 17)); 68 float *fp1 = second_arg_pair(make_pair(ip, 17), make_pair(fp, 17)); 69 float *fp2 = second_arg_pair(make_pair(ip, 17), make_pair(fp, 17), 70 make_pair(dp, 17)); 71 no_type nt1 = first_arg_pair(); 72 no_type nt2 = second_arg_pair(); 73 no_type nt3 = second_arg_pair(make_pair(ip, 17)); 74 75 76 first_arg_pair(make_pair(ip, 17), 16); // expected-error{{no matching function for call to 'first_arg_pair'}} 77 } 78 79 // For a function parameter pack that does not occur at the end of the 80 // parameter-declaration-list, the type of the parameter pack is a 81 // non-deduced context. 82 template<typename ...Types> struct tuple { }; 83 84 template<typename ...Types> 85 void pack_not_at_end(tuple<Types...>, Types... values, int); 86 87 void test_pack_not_at_end(tuple<int*, double*> t2) { 88 pack_not_at_end(t2, 0, 0, 0); 89 } 90