From Jason Turner

[temp.arg.nontype]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpyve44kjo/{from.md → to.md} +84 -22
tmp/tmpyve44kjo/{from.md → to.md} RENAMED
@@ -1,40 +1,87 @@
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 { ... };
38
  int ai[10];
39
  X<ai> xi; // array to pointer and qualification conversions
40
 
@@ -57,20 +104,35 @@ A<&f> a; // selects f(int)
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
  };
@@ -93,13 +155,13 @@ X<A, "Pyrophoricity"> z; // OK, string-literal is a constructor argument
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
 
1
+ ### Constant template arguments <a id="temp.arg.nontype">[[temp.arg.nontype]]</a>
2
 
3
+ A template argument E for a constant template parameter with declared
4
+ type `T` shall be such that the invented declaration
 
 
5
 
6
  ``` cpp
7
+ T x = E ;
8
  ```
9
 
10
+ satisfies the semantic constraints for the definition of a `constexpr`
11
+ variable with static storage duration [[dcl.constexpr]]. If `T` contains
12
+ a placeholder type [[dcl.spec.auto]] or a placeholder for a deduced
13
+ class type [[dcl.type.class.deduct]], the type of the parameter is
14
+ deduced from the above declaration.
15
 
16
+ [*Note 1*: E is a *template-argument* or (for a default template
17
+ argument) an *initializer-clause*. *end note*]
 
18
 
19
+ If the parameter type thus deduced is not permitted for a constant
20
+ template parameter [[temp.param]], the program is ill-formed.
 
21
 
22
+ The value of a constant template parameter P of (possibly deduced) type
23
+ `T` is determined from its template argument A as follows. If `T` is not
24
+ a class type and A is not a *braced-init-list*, A shall be a converted
25
+ constant expression [[expr.const]] of type `T`; the value of P is A (as
26
+ converted).
27
+
28
+ Otherwise, a temporary variable
29
+
30
+ ``` cpp
31
+ constexpr T v = A;
32
+ ```
33
+
34
+ is introduced. The lifetime of `v` ends immediately after initializing
35
+ it and any template parameter object (see below). For each such
36
+ variable, the *id-expression* `v` is termed a *candidate initializer*.
37
+
38
+ If `T` is a class type, a template parameter object [[temp.param]]
39
+ exists that is constructed so as to be template-argument-equivalent to
40
+ `v`; P denotes that template parameter object. P is copy-initialized
41
+ from an unspecified candidate initializer that is
42
+ template-argument-equivalent to `v`. If, for the initialization from any
43
+ candidate initializer,
44
+
45
+ - the initialization would be ill-formed, or
46
+ - the full-expression of an invented *init-declarator* for the
47
+ initialization would not be a constant expression when interpreted as
48
+ a *constant-expression* [[expr.const]], or
49
+ - the initialization would cause P to not be
50
+ template-argument-equivalent [[temp.type]] to `v`,
51
+
52
+ the program is ill-formed.
53
+
54
+ Otherwise, the value of P is that of v.
55
+
56
+ For a constant template parameter of reference or pointer type, or for
57
+ each non-static data member of reference or pointer type in a constant
58
+ template parameter of class type or subobject thereof, the reference or
59
+ pointer value shall not refer or point to (respectively):
60
 
61
  - a temporary object [[class.temporary]],
62
  - a string literal object [[lex.string]],
63
  - the result of a `typeid` expression [[expr.typeid]],
64
  - a predefined `__func__` variable [[dcl.fct.def.general]], or
65
  - a subobject [[intro.object]] of one of the above.
66
 
67
  [*Example 1*:
68
 
69
+ ``` cpp
70
+ template <int& r> class A{};
71
+ extern int x;
72
+ A<x> a; // OK
73
+ void f(int p) {
74
+ constexpr int& r = p; // OK
75
+ A<r> a; // error: a static constexpr int& variable cannot be initialized to refer to p here
76
+ }
77
+ ```
78
+
79
+ — *end example*]
80
+
81
+ [*Example 2*:
82
+
83
  ``` cpp
84
  template<const int* pci> struct X { ... };
85
  int ai[10];
86
  X<ai> xi; // array to pointer and qualification conversions
87
 
 
104
  template<auto n> struct B { ... };
105
  B<5> b1; // OK, template parameter type is int
106
  B<'a'> b2; // OK, template parameter type is char
107
  B<2.5> b3; // OK, template parameter type is double
108
  B<void(0)> b4; // error: template parameter type cannot be void
109
+
110
+ template<int i> struct C { /* ... */ };
111
+ C<{ 42 }> c1; // OK
112
+
113
+ struct J1 {
114
+ J1 *self = this;
115
+ };
116
+ B<J1{}> j1; // error: initialization of template parameter object is not a constant expression
117
+
118
+ struct J2 {
119
+ J2 *self = this;
120
+ constexpr J2() {}
121
+ constexpr J2(const J2&) {}
122
+ };
123
+ B<J2{}> j2; // error: template parameter object not template-argument-equivalent to introduced temporary
124
  ```
125
 
126
  — *end example*]
127
 
128
  [*Note 2*:
129
 
130
  A *string-literal* [[lex.string]] is not an acceptable
131
+ *template-argument* for a constant template parameter of non-class type.
132
 
133
+ [*Example 3*:
134
 
135
  ``` cpp
136
  template<class T, T p> class X {
137
  ...
138
  };
 
155
  — *end note*]
156
 
157
  [*Note 3*:
158
 
159
  A temporary object is not an acceptable *template-argument* when the
160
+ corresponding template parameter has reference type.
161
 
162
+ [*Example 4*:
163
 
164
  ``` cpp
165
  template<const int& CRI> struct B { ... };
166
 
167
  B<1> b1; // error: temporary would be required for template argument