From Jason Turner

[temp.arg.nontype]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmp16dn37ig/{from.md → to.md} +51 -52
tmp/tmp16dn37ig/{from.md → to.md} RENAMED
@@ -1,29 +1,37 @@
1
  ### Template non-type arguments <a id="temp.arg.nontype">[[temp.arg.nontype]]</a>
2
 
3
- If the type of a *template-parameter* contains a placeholder type (
4
- [[dcl.spec.auto]], [[temp.param]]), the deduced parameter type is
5
- determined from the type of the *template-argument* by placeholder type
6
- deduction ([[dcl.type.auto.deduct]]). If a deduced parameter type is
7
- not permitted for a *template-parameter* declaration ([[temp.param]]),
8
- the program is ill-formed.
 
 
 
 
 
9
 
10
  A *template-argument* for a non-type *template-parameter* shall be a
11
- converted constant expression ([[expr.const]]) of the type of the
12
- *template-parameter*. For a non-type *template-parameter* of reference
13
- or pointer type, the value of the constant expression shall not refer to
14
- (or for a pointer type, shall not be the address of):
15
 
16
- - a subobject ([[intro.object]]),
17
- - a temporary object ([[class.temporary]]),
18
- - a string literal ([[lex.string]]),
19
- - the result of a `typeid` expression ([[expr.typeid]]), or
20
- - a predefined `__func__` variable ([[dcl.fct.def.general]]).
21
 
22
- [*Note 1*: If the *template-argument* represents a set of overloaded
23
- functions (or a pointer or member pointer to such), the matching
24
- function is selected from the set ([[over.over]]). *end note*]
 
 
 
 
 
 
 
25
 
26
  [*Example 1*:
27
 
28
  ``` cpp
29
  template<const int* pci> struct X { ... };
@@ -45,76 +53,67 @@ void f(int);
45
  template<void (*pf)(int)> struct A { ... };
46
 
47
  A<&f> a; // selects f(int)
48
 
49
  template<auto n> struct B { ... };
50
- B<5> b1; // OK: template parameter type is int
51
- B<'a'> b2; // OK: template parameter type is char
52
- B<2.5> b3; // error: template parameter type cannot be double
 
53
  ```
54
 
55
  — *end example*]
56
 
57
  [*Note 2*:
58
 
59
- A string literal ([[lex.string]]) is not an acceptable
60
- *template-argument*.
61
 
62
  [*Example 2*:
63
 
64
  ``` cpp
65
- template<class T, const char* p> class X {
66
  ...
67
  };
68
 
69
- X<int, "Studebaker"> x1; // error: string literal as template-argument
 
70
 
71
  const char p[] = "Vivisectionist";
72
- X<int,p> x2; // OK
 
 
 
 
 
 
73
  ```
74
 
75
  — *end example*]
76
 
77
  — *end note*]
78
 
79
  [*Note 3*:
80
 
81
- The address of an array element or non-static data member is not an
82
- acceptable *template-argument*.
83
-
84
- [*Example 3*:
85
-
86
- ``` cpp
87
- template<int* p> class X { };
88
-
89
- int a[10];
90
- struct S { int m; static int s; } s;
91
-
92
- X<&a[2]> x3; // error: address of array element
93
- X<&s.m> x4; // error: address of non-static member
94
- X<&s.s> x5; // OK: address of static member
95
- X<&S::s> x6; // OK: address of static member
96
- ```
97
-
98
- — *end example*]
99
-
100
- — *end note*]
101
-
102
- [*Note 4*:
103
-
104
  A temporary object is not an acceptable *template-argument* when the
105
  corresponding *template-parameter* has reference type.
106
 
107
- [*Example 4*:
108
 
109
  ``` cpp
110
  template<const int& CRI> struct B { ... };
111
 
112
- B<1> b2; // error: temporary would be required for template argument
113
 
114
  int c = 1;
115
- B<c> b1; // OK
 
 
 
 
 
 
116
  ```
117
 
118
  — *end example*]
119
 
120
  — *end note*]
 
1
  ### Template non-type arguments <a id="temp.arg.nontype">[[temp.arg.nontype]]</a>
2
 
3
+ If the type `T` of a *template-parameter* [[temp.param]] contains a
4
+ placeholder type [[dcl.spec.auto]] or a placeholder for a deduced class
5
+ type [[dcl.type.class.deduct]], the type of the parameter is the type
6
+ deduced for the variable `x` in the invented declaration
7
+
8
+ ``` cpp
9
+ T x = template-argument ;
10
+ ```
11
+
12
+ If a deduced parameter type is not permitted for a *template-parameter*
13
+ declaration [[temp.param]], the program is ill-formed.
14
 
15
  A *template-argument* for a non-type *template-parameter* shall be a
16
+ converted constant expression [[expr.const]] of the type of the
17
+ *template-parameter*.
 
 
18
 
19
+ [*Note 1*: If the *template-argument* is an overload set (or the
20
+ address of such, including forming a pointer-to-member), the matching
21
+ function is selected from the set [[over.over]]. — *end note*]
 
 
22
 
23
+ For a non-type *template-parameter* of reference or pointer type, or for
24
+ each non-static data member of reference or pointer type in a non-type
25
+ *template-parameter* of class type or subobject thereof, the reference
26
+ or pointer value shall not refer to or be the address of (respectively):
27
+
28
+ - a temporary object [[class.temporary]],
29
+ - a string literal object [[lex.string]],
30
+ - the result of a `typeid` expression [[expr.typeid]],
31
+ - a predefined `__func__` variable [[dcl.fct.def.general]], or
32
+ - a subobject [[intro.object]] of one of the above.
33
 
34
  [*Example 1*:
35
 
36
  ``` cpp
37
  template<const int* pci> struct X { ... };
 
53
  template<void (*pf)(int)> struct A { ... };
54
 
55
  A<&f> a; // selects f(int)
56
 
57
  template<auto n> struct B { ... };
58
+ B<5> b1; // OK, template parameter type is int
59
+ B<'a'> b2; // OK, template parameter type is char
60
+ B<2.5> b3; // OK, template parameter type is double
61
+ B<void(0)> b4; // error: template parameter type cannot be void
62
  ```
63
 
64
  — *end example*]
65
 
66
  [*Note 2*:
67
 
68
+ A *string-literal* [[lex.string]] is not an acceptable
69
+ *template-argument* for a *template-parameter* of non-class type.
70
 
71
  [*Example 2*:
72
 
73
  ``` cpp
74
+ template<class T, T p> class X {
75
  ...
76
  };
77
 
78
+ X<const char*, "Studebaker"> x; // error: string literal object as template-argument
79
+ X<const char*, "Knope" + 1> x2; // error: subobject of string literal object as template-argument
80
 
81
  const char p[] = "Vivisectionist";
82
+ X<const char*, p> y; // OK
83
+
84
+ struct A {
85
+ constexpr A(const char*) {}
86
+ };
87
+
88
+ X<A, "Pyrophoricity"> z; // OK, string-literal is a constructor argument to A
89
  ```
90
 
91
  — *end example*]
92
 
93
  — *end note*]
94
 
95
  [*Note 3*:
96
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
97
  A temporary object is not an acceptable *template-argument* when the
98
  corresponding *template-parameter* has reference type.
99
 
100
+ [*Example 3*:
101
 
102
  ``` cpp
103
  template<const int& CRI> struct B { ... };
104
 
105
+ B<1> b1; // error: temporary would be required for template argument
106
 
107
  int c = 1;
108
+ B<c> b2; // OK
109
+
110
+ struct X { int n; };
111
+ struct Y { const int &r; };
112
+ template<Y y> struct C { ... };
113
+ C<Y{X{1}.n}> c; // error: subobject of temporary object used to initialize
114
+ // reference member of template parameter
115
  ```
116
 
117
  — *end example*]
118
 
119
  — *end note*]