p5.cpp revision eedf3e99c711b120b82b12a5a087e4a1e5c52222
1// RUN: %clang_cc1 -fsyntax-only -verify %s 2 3// C++0x [temp.arg.nontype] p5: 4// The following conversions are performed on each expression used as 5// a non-type template-argument. If a non-type template-argument cannot be 6// converted to the type of the corresponding template-parameter then the 7// program is ill-formed. 8// -- for a non-type template-parameter of integral or enumeration type, 9// integral promotions (4.5) and integral conversions (4.7) are applied. 10// -- for a non-type template-parameter of type pointer to object, 11// qualification conversions (4.4) and the array-to-pointer conversion 12// (4.2) are applied; if the template-argument is of type 13// std::nullptr_t, the null pointer conversion (4.10) is applied. 14// -- For a non-type template-parameter of type reference to object, no 15// conversions apply. The type referred to by the reference may be more 16// cv-qualified than the (otherwise identical) type of the 17// template-argument. The template-parameter is bound directly to the 18// template-argument, which shall be an lvalue. 19namespace reference_parameters { 20 template <int& N> struct S0 { }; // expected-note 3 {{template parameter is declared here}} 21 template <const int& N> struct S1 { }; // expected-note 2 {{template parameter is declared here}} 22 template <volatile int& N> struct S2 { }; // expected-note 2 {{template parameter is declared here}} 23 template <const volatile int& N> struct S3 { }; 24 int i; 25 extern const int ci; 26 volatile int vi; 27 extern const volatile int cvi; 28 void test() { 29 S0<i> s0; 30 S0<ci> s0c; // expected-error{{reference binding of non-type template parameter of type 'int &' to template argument of type 'int const' ignores qualifiers}} 31 S0<vi> s0v; // expected-error{{reference binding of non-type template parameter of type 'int &' to template argument of type 'int volatile' ignores qualifiers}} 32 S0<cvi> s0cv; // expected-error{{reference binding of non-type template parameter of type 'int &' to template argument of type 'int const volatile' ignores qualifiers}} 33 34 S1<i> s1; 35 S1<ci> s1c; 36 S1<vi> s1v; // expected-error{{reference binding of non-type template parameter of type 'int const &' to template argument of type 'int volatile' ignores qualifiers}} 37 S1<cvi> s1cv; // expected-error{{reference binding of non-type template parameter of type 'int const &' to template argument of type 'int const volatile' ignores qualifiers}} 38 39 S2<i> s2; 40 S2<ci> s2c; // expected-error{{reference binding of non-type template parameter of type 'int volatile &' to template argument of type 'int const' ignores qualifiers}} 41 S2<vi> s2v; 42 S2<cvi> s2cv; // expected-error{{reference binding of non-type template parameter of type 'int volatile &' to template argument of type 'int const volatile' ignores qualifiers}} 43 44 S3<i> s3; 45 S3<ci> s3c; 46 S3<vi> s3v; 47 S3<cvi> s3cv; 48 } 49} 50 51// -- For a non-type template-parameter of type pointer to function, the 52// function-to-pointer conversion (4.3) is applied; if the 53// template-argument is of type std::nullptr_t, the null pointer 54// conversion (4.10) is applied. If the template-argument represents 55// a set of overloaded functions (or a pointer to such), the matching 56// function is selected from the set (13.4). 57// -- For a non-type template-parameter of type reference to function, no 58// conversions apply. If the template-argument represents a set of 59// overloaded functions, the matching function is selected from the set 60// (13.4). 61// -- For a non-type template-parameter of type pointer to member function, 62// if the template-argument is of type std::nullptr_t, the null member 63// pointer conversion (4.11) is applied; otherwise, no conversions 64// apply. If the template-argument represents a set of overloaded member 65// functions, the matching member function is selected from the set 66// (13.4). 67// -- For a non-type template-parameter of type pointer to data member, 68// qualification conversions (4.4) are applied; if the template-argument 69// is of type std::nullptr_t, the null member pointer conversion (4.11) 70// is applied. 71