// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
template<typename ...Types> struct tuple;
template<unsigned> struct unsigned_c;
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;
};
namespace PackExpansionNotAtEnd {
template<typename T, typename U>
struct tuple_same_with_int {
static const bool value = false;
};
template<typename ...Types>
struct tuple_same_with_int<tuple<Types...>, tuple<Types..., int>> {
static const bool value = true;
};
int tuple_same_with_int_1[tuple_same_with_int<tuple<int, float, double>,
tuple<int, float, double, int>
>::value? 1 : -1];
template<typename ... Types> struct UselessPartialSpec;
template<typename ... Types, // expected-note{{non-deducible template parameter 'Types'}}
typename Tail> // expected-note{{non-deducible template parameter 'Tail'}}
struct UselessPartialSpec<Types..., Tail>; // expected-error{{class template partial specialization contains template parameters that cannot be deduced; this partial specialization will never be used}}
}
// When a pack expansion occurs within a template argument list, the entire
// list is a non-deduced context. For the corresponding case in a function
// parameter list, only that parameter is non-deduced.
//
// FIXME: It's not clear that this difference is intended, but the wording is
// explicit.
namespace PackExpansionNotAtEndFunctionVersusTemplate {
template<typename ...T> struct X {};
template<typename ...T, typename U> void f1(void(T..., U));
// expected-note@+1 {{couldn't infer template argument 'U'}}
template<typename ...T, typename U> void f2(X<T..., U>); // FIXME: ill-formed, U is not deducible
void g(int, int, int);
X<int, int, int> h;
void test() {
// This is deducible: the T... parameter is a non-deduced context, but
// that's OK because we don't need to deduce it.
f1<int, int>(g);
// This is not deducible: the T... parameter renders the entire
// template-argument-list a non-deduced context, so U is not deducible.
f2<int, int>(h); // expected-error {{no matching function}}
}
template<typename T> struct Y;
template<typename ...T, // expected-note {{non-deducible template parameter 'T'}}
typename U>
struct Y<void(T..., U)> {}; // expected-error {{cannot be deduced}}
template<typename ...T, // expected-note {{non-deducible template parameter 'T'}}
typename U> // expected-note {{non-deducible template parameter 'U'}}
struct Y<X<T..., U>>; // expected-error {{cannot be deduced}}
// FIXME: T is not deducible here, due to [temp.deduct.call]p1:
// "When a function parameter pack appears in a non-deduced context,
// the type of that pack is never deduced."
template<typename ...T,
typename U>
struct Y<void(T..., U, T...)> {};
}
namespace DeduceNonTypeTemplateArgsInArray {
template<typename ...ArrayTypes>
struct split_arrays;
template<typename ...ElementTypes, unsigned ...Bounds>
struct split_arrays<ElementTypes[Bounds]...> {
typedef tuple<ElementTypes...> element_types;
// FIXME: Would like to have unsigned_tuple<Bounds...> here.
typedef tuple<unsigned_c<Bounds>...> bounds_types;
};
int check1[is_same<split_arrays<int[1], float[2], double[3]>::element_types,
tuple<int, float, double>>::value? 1 : -1];
int check2[is_same<split_arrays<int[1], float[2], double[3]>::bounds_types,
tuple<unsigned_c<1>, unsigned_c<2>, unsigned_c<3>>
>::value? 1 : -1];
}
namespace DeduceWithDefaultArgs {
template<template<typename...> class Container> void f(Container<int>); // expected-note {{deduced type 'X<[...], (default) int>' of 1st parameter does not match adjusted type 'X<[...], double>' of argument [with Container = DeduceWithDefaultArgs::X]}}
template<typename, typename = int> struct X {};
void g() {
// OK, use default argument for the second template parameter.
f(X<int>{});
f(X<int, int>{});
// Not OK.
f(X<int, double>{}); // expected-error {{no matching function for call to 'f'}}
}
}