From Jason Turner

[temp.arg.nontype]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpztklmvbm/{from.md → to.md} +82 -97
tmp/tmpztklmvbm/{from.md → to.md} RENAMED
@@ -1,136 +1,121 @@
1
  ### Template non-type arguments <a id="temp.arg.nontype">[[temp.arg.nontype]]</a>
2
 
3
- A *template-argument* for a non-type, non-template *template-parameter*
4
- shall be one of:
 
 
 
 
5
 
6
- - for a non-type *template-parameter* of integral or enumeration type, a
7
  converted constant expression ([[expr.const]]) of the type of the
8
- *template-parameter*; or
9
- - the name of a non-type *template-parameter*; or
10
- - a constant expression ([[expr.const]]) that designates the address of
11
- a complete object with static storage duration and external or
12
- internal linkage or a function with external or internal linkage,
13
- including function templates and function *template-id*s but excluding
14
- non-static class members, expressed (ignoring parentheses) as `&`
15
- *id-expression*, where the *id-expression* is the name of an object or
16
- function, except that the `&` may be omitted if the name refers to a
17
- function or array and shall be omitted if the corresponding
18
- *template-parameter* is a reference; or
19
- - a constant expression that evaluates to a null pointer value (
20
- [[conv.ptr]]); or
21
- - a constant expression that evaluates to a null member pointer value (
22
- [[conv.mem]]); or
23
- - a pointer to member expressed as described in  [[expr.unary.op]]; or
24
- - a constant expression of type `std::nullptr_t`.
25
-
26
- A string literal ([[lex.string]]) does not satisfy the requirements of
27
- any of these categories and thus is not an acceptable
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28
  *template-argument*.
29
 
 
 
30
  ``` cpp
31
  template<class T, const char* p> class X {
32
- /* ... */
33
  };
34
 
35
  X<int, "Studebaker"> x1; // error: string literal as template-argument
36
 
37
  const char p[] = "Vivisectionist";
38
  X<int,p> x2; // OK
39
  ```
40
 
41
- Addresses of array elements and names or addresses of non-static class
42
- members are not acceptable *template-argument*s.
 
 
 
 
 
 
 
 
43
 
44
  ``` cpp
45
  template<int* p> class X { };
46
 
47
  int a[10];
48
  struct S { int m; static int s; } s;
49
 
50
  X<&a[2]> x3; // error: address of array element
51
  X<&s.m> x4; // error: address of non-static member
52
- X<&s.s> x5; // error: &S::s must be used
53
  X<&S::s> x6; // OK: address of static member
54
  ```
55
 
56
- Temporaries, unnamed lvalues, and named lvalues with no linkage are not
57
- acceptable *template-argument*s when the corresponding
58
- *template-parameter* has reference type.
 
 
 
 
 
 
 
59
 
60
  ``` cpp
61
- template<const int& CRI> struct B { /* ... */ };
62
 
63
  B<1> b2; // error: temporary would be required for template argument
64
 
65
  int c = 1;
66
  B<c> b1; // OK
67
  ```
68
 
69
- The following conversions are performed on each expression used as a
70
- non-type *template-argument*. If a non-type *template-argument* cannot
71
- be converted to the type of the corresponding *template-parameter* then
72
- the program is ill-formed.
73
 
74
- - For a non-type *template-parameter* of integral or enumeration type,
75
- conversions permitted in a converted constant expression (
76
- [[expr.const]]) are applied.
77
- - for a non-type *template-parameter* of type pointer to object,
78
- qualification conversions ([[conv.qual]]) and the array-to-pointer
79
- conversion ([[conv.array]]) are applied; if the *template-argument*
80
- is of type `std::nullptr_t`, the null pointer conversion (
81
- [[conv.ptr]]) is applied. In particular, neither the null pointer
82
- conversion for a zero-valued integer literal ([[conv.ptr]]) nor the
83
- derived-to-base conversion ([[conv.ptr]]) are applied. Although `0`
84
- is a valid *template-argument* for a non-type *template-parameter* of
85
- integral type, it is not a valid *template-argument* for a non-type
86
- *template-parameter* of pointer type. However, both `(int*)0` and
87
- `nullptr` are valid *template-argument*s for a non-type
88
- *template-parameter* of type “pointer to int.”
89
- - For a non-type *template-parameter* of type reference to object, no
90
- conversions apply. The type referred to by the reference may be more
91
- cv-qualified than the (otherwise identical) type of the
92
- *template-argument*. The *template-parameter* is bound directly to the
93
- *template-argument*, which shall be an lvalue.
94
- - For a non-type *template-parameter* of type pointer to function, the
95
- function-to-pointer conversion ([[conv.func]]) is applied; if the
96
- *template-argument* is of type `std::nullptr_t`, the null pointer
97
- conversion ([[conv.ptr]]) is applied. If the *template-argument*
98
- represents a set of overloaded functions (or a pointer to such), the
99
- matching function is selected from the set ([[over.over]]).
100
- - For a non-type *template-parameter* of type reference to function, no
101
- conversions apply. If the *template-argument* represents a set of
102
- overloaded functions, the matching function is selected from the set (
103
- [[over.over]]).
104
- - For a non-type *template-parameter* of type pointer to member
105
- function, if the *template-argument* is of type `std::nullptr_t`, the
106
- null member pointer conversion ([[conv.mem]]) is applied; otherwise,
107
- no conversions apply. If the *template-argument* represents a set of
108
- overloaded member functions, the matching member function is selected
109
- from the set ([[over.over]]).
110
- - For a non-type *template-parameter* of type pointer to data member,
111
- qualification conversions ([[conv.qual]]) are applied; if the
112
- *template-argument* is of type `std::nullptr_t`, the null member
113
- pointer conversion ([[conv.mem]]) is applied.
114
-
115
- ``` cpp
116
- template<const int* pci> struct X { /* ... */ };
117
- int ai[10];
118
- X<ai> xi; // array to pointer and qualification conversions
119
-
120
- struct Y { /* ... */ };
121
- template<const Y& b> struct Z { /* ... */ };
122
- Y y;
123
- Z<y> z; // no conversion, but note extra cv-qualification
124
-
125
- template<int (&pa)[5]> struct W { /* ... */ };
126
- int b[5];
127
- W<b> w; // no conversion
128
-
129
- void f(char);
130
- void f(int);
131
-
132
- template<void (*pf)(int)> struct A { /* ... */ };
133
-
134
- A<&f> a; // selects f(int)
135
- ```
136
 
 
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 { ... };
30
+ int ai[10];
31
+ X<ai> xi; // array to pointer and qualification conversions
32
+
33
+ struct Y { ... };
34
+ template<const Y& b> struct Z { ... };
35
+ Y y;
36
+ Z<y> z; // no conversion, but note extra cv-qualification
37
+
38
+ template<int (&pa)[5]> struct W { ... };
39
+ int b[5];
40
+ W<b> w; // no conversion
41
+
42
+ void f(char);
43
+ void f(int);
44
+
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*]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
121