aboutsummaryrefslogtreecommitdiff
path: root/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p21.cpp
blob: 20e6ea2d7127082ee5c49dc1199d32a9ee16155e (plain) (blame)
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
// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
// expected-no-diagnostics

// Note: Template argument deduction involving parameter packs
// (14.5.3) can deduce zero or more arguments for each parameter pack.

template<class> struct X { 
  static const unsigned value = 0;
}; 

template<class R, class ... ArgTypes> struct X<R(int, ArgTypes ...)> { 
  static const unsigned value = 1;
}; 

template<class ... Types> struct Y { 
  static const unsigned value = 0;
}; 

template<class T, class ... Types> struct Y<T, Types& ...> { 
  static const unsigned value = 1;
};

template<class ... Types> int f(void (*)(Types ...)); 
void g(int, float);

int check0[X<int>::value == 0? 1 : -1]; // uses primary template
int check1[X<int(int, float, double)>::value == 1? 1 : -1]; // uses partial specialization
int check2[X<int(float, int)>::value == 0? 1 : -1]; // uses primary template
int check3[Y<>::value == 0? 1 : -1]; // uses primary template
int check4[Y<int&, float&, double&>::value == 1? 1 : -1]; // uses partial specialization
int check5[Y<int, float, double>::value == 0? 1 : -1]; // uses primary template
int fv = f(g); // okay