- tmp/tmpmunk95tt/{from.md → to.md} +140 -208
tmp/tmpmunk95tt/{from.md → to.md}
RENAMED
|
@@ -1,271 +1,203 @@
|
|
| 1 |
## Exception specifications <a id="except.spec">[[except.spec]]</a>
|
| 2 |
|
| 3 |
-
|
| 4 |
-
|
| 5 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 6 |
|
| 7 |
``` bnf
|
| 8 |
-
|
| 9 |
-
dynamic-exception-specification
|
| 10 |
-
noexcept-specification
|
| 11 |
-
```
|
| 12 |
-
|
| 13 |
-
``` bnf
|
| 14 |
-
dynamic-exception-specification:
|
| 15 |
-
'throw (' type-id-listₒₚₜ ')'
|
| 16 |
-
```
|
| 17 |
-
|
| 18 |
-
``` bnf
|
| 19 |
-
type-id-list:
|
| 20 |
-
type-id '...'ₒₚₜ
|
| 21 |
-
type-id-list ',' type-id '...'ₒₚₜ
|
| 22 |
-
```
|
| 23 |
-
|
| 24 |
-
``` bnf
|
| 25 |
-
noexcept-specification:
|
| 26 |
'noexcept' '(' constant-expression ')'
|
| 27 |
'noexcept'
|
|
|
|
| 28 |
```
|
| 29 |
|
| 30 |
-
In a *noexcept-
|
| 31 |
-
|
| 32 |
-
|
| 33 |
-
|
| 34 |
-
`noexcept` is part of the *noexcept-
|
| 35 |
-
an initializer ([[dcl.init]]).
|
| 36 |
-
|
| 37 |
-
|
| 38 |
-
|
| 39 |
-
|
| 40 |
-
|
| 41 |
-
|
| 42 |
-
|
| 43 |
-
|
| 44 |
-
|
| 45 |
-
|
| 46 |
-
|
| 47 |
-
|
| 48 |
-
|
| 49 |
-
|
| 50 |
-
|
| 51 |
-
|
| 52 |
-
|
| 53 |
-
|
| 54 |
-
|
| 55 |
-
or “function returning `T`” denoted in an *exception-specification* is
|
| 56 |
-
adjusted to type `T`, “pointer to `T`”, or “pointer to function
|
| 57 |
-
returning `T`”, respectively.
|
| 58 |
-
|
| 59 |
-
Two *exception-specification*s are *compatible* if:
|
| 60 |
-
|
| 61 |
-
- both are non-throwing (see below), regardless of their form,
|
| 62 |
-
- both have the form `noexcept(`*constant-expression*`)` and the
|
| 63 |
-
*constant-expression*s are equivalent, or
|
| 64 |
-
- both are *dynamic-exception-specification*s that have the same set of
|
| 65 |
-
adjusted types.
|
| 66 |
-
|
| 67 |
-
If any declaration of a function has an *exception-specification* that
|
| 68 |
-
is not a *noexcept-specification* allowing all exceptions, all
|
| 69 |
-
declarations, including the definition and any explicit specialization,
|
| 70 |
-
of that function shall have a compatible *exception-specification*. If
|
| 71 |
-
any declaration of a pointer to function, reference to function, or
|
| 72 |
-
pointer to member function has an *exception-specification*, all
|
| 73 |
-
occurrences of that declaration shall have a compatible
|
| 74 |
-
*exception-specification* In an explicit instantiation an
|
| 75 |
-
*exception-specification* may be specified, but is not required. If an
|
| 76 |
-
*exception-specification* is specified in an explicit instantiation
|
| 77 |
-
directive, it shall be compatible with the *exception-specification*s of
|
| 78 |
-
other declarations of that function. A diagnostic is required only if
|
| 79 |
-
the *exception-specification*s are not compatible within a single
|
| 80 |
-
translation unit.
|
| 81 |
-
|
| 82 |
-
If a virtual function has an *exception-specification*, all
|
| 83 |
declarations, including the definition, of any function that overrides
|
| 84 |
-
that virtual function in any derived class shall
|
| 85 |
-
|
| 86 |
-
|
|
|
|
|
|
|
| 87 |
|
| 88 |
``` cpp
|
| 89 |
struct B {
|
| 90 |
-
virtual void f()
|
| 91 |
virtual void g();
|
|
|
|
| 92 |
};
|
| 93 |
|
| 94 |
struct D: B {
|
| 95 |
void f(); // ill-formed
|
| 96 |
-
void g()
|
|
|
|
| 97 |
};
|
| 98 |
```
|
| 99 |
|
| 100 |
-
The declaration of `D::f` is ill-formed because it
|
| 101 |
-
|
| 102 |
-
|
| 103 |
-
functions, pointers to member functions, and references to functions:
|
| 104 |
-
the target entity shall allow at least the exceptions allowed by the
|
| 105 |
-
source value in the assignment or initialization.
|
| 106 |
|
| 107 |
-
|
| 108 |
-
class A { /* ... */ };
|
| 109 |
-
void (*pf1)(); // no exception specification
|
| 110 |
-
void (*pf2)() throw(A);
|
| 111 |
-
|
| 112 |
-
void f() {
|
| 113 |
-
pf1 = pf2; // OK: pf1 is less restrictive
|
| 114 |
-
pf2 = pf1; // error: pf2 is more restrictive
|
| 115 |
-
}
|
| 116 |
-
```
|
| 117 |
-
|
| 118 |
-
In such an assignment or initialization, *exception-specification*s on
|
| 119 |
-
return types and parameter types shall be compatible. In other
|
| 120 |
-
assignments or initializations, *exception-specification*s shall be
|
| 121 |
-
compatible.
|
| 122 |
-
|
| 123 |
-
An *exception-specification* can include the same type more than once
|
| 124 |
-
and can include classes that are related by inheritance, even though
|
| 125 |
-
doing so is redundant. An *exception-specification* can also include the
|
| 126 |
-
class `std::bad_exception` ([[bad.exception]]).
|
| 127 |
-
|
| 128 |
-
A function is said to *allow* an exception of type `E` if the
|
| 129 |
-
*constant-expression* in its *noexcept-specification* evaluates to
|
| 130 |
-
`false` or its *dynamic-exception-specification* contains a type `T` for
|
| 131 |
-
which a handler of type `T` would be a match ([[except.handle]]) for an
|
| 132 |
-
exception of type `E`.
|
| 133 |
|
| 134 |
Whenever an exception is thrown and the search for a handler (
|
| 135 |
-
[[except.handle]]) encounters the outermost block of a function with
|
| 136 |
-
|
|
|
|
| 137 |
|
| 138 |
-
|
| 139 |
-
|
| 140 |
-
|
| 141 |
-
|
| 142 |
-
|
| 143 |
|
| 144 |
``` cpp
|
| 145 |
-
|
| 146 |
-
class Y { };
|
| 147 |
-
class Z: public X { };
|
| 148 |
-
class W { };
|
| 149 |
|
| 150 |
-
void
|
| 151 |
-
|
| 152 |
-
|
| 153 |
-
if (n) throw Z(); // also OK
|
| 154 |
-
throw W(); // will call std::unexpected()
|
| 155 |
}
|
| 156 |
```
|
| 157 |
|
| 158 |
-
|
| 159 |
-
|
| 160 |
-
definition is used.
|
| 161 |
|
| 162 |
-
|
| 163 |
-
*exception-specification* for which it was invoked, and in this case the
|
| 164 |
-
search for another handler will continue at the call of the function
|
| 165 |
-
with this *exception-specification* (see [[except.unexpected]]), or it
|
| 166 |
-
may call `std::terminate()`.
|
| 167 |
|
| 168 |
-
An
|
| 169 |
-
executed it throws or might throw an exception that the containing
|
| 170 |
-
function does not allow.
|
| 171 |
|
| 172 |
-
``
|
| 173 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 174 |
|
| 175 |
-
|
| 176 |
-
|
| 177 |
-
|
| 178 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 179 |
|
| 180 |
-
|
| 181 |
-
|
|
|
|
|
|
|
| 182 |
|
| 183 |
-
|
| 184 |
-
|
| 185 |
-
|
| 186 |
-
|
| 187 |
-
|
| 188 |
-
`noexcept(`*constant-expression*`)` where the *constant-expression*
|
| 189 |
-
yields `true`. A function with a non-throwing *exception-specification*
|
| 190 |
-
does not allow any exceptions.
|
| 191 |
|
| 192 |
-
|
| 193 |
-
|
|
|
|
| 194 |
|
| 195 |
-
|
| 196 |
-
declared special member function (Clause [[special]]) have an
|
| 197 |
-
*exception-specification*. If `f` is an inheriting constructor or an
|
| 198 |
-
implicitly declared default constructor, copy constructor, move
|
| 199 |
-
constructor, destructor, copy assignment operator, or move assignment
|
| 200 |
-
operator, its implicit *exception-specification* specifies the *type-id*
|
| 201 |
-
`T` if and only if `T` is allowed by the *exception-specification* of a
|
| 202 |
-
function directly invoked by `f`’s implicit definition; `f` allows all
|
| 203 |
-
exceptions if any function it directly invokes allows all exceptions,
|
| 204 |
-
and `f` has the *exception-specification* `noexcept(true)` if every
|
| 205 |
-
function it directly invokes allows no exceptions. It follows that `f`
|
| 206 |
-
has the *exception-specification* `noexcept(true)` if it invokes no
|
| 207 |
-
other functions. An instantiation of an inheriting constructor template
|
| 208 |
-
has an implied *exception-specification* as if it were a non-template
|
| 209 |
-
inheriting constructor.
|
| 210 |
|
| 211 |
``` cpp
|
| 212 |
struct A {
|
| 213 |
-
A();
|
| 214 |
-
A(const A&)
|
| 215 |
-
A(A&&)
|
| 216 |
-
~A()
|
| 217 |
};
|
| 218 |
struct B {
|
| 219 |
B() throw();
|
| 220 |
-
B(const B&) = default;
|
| 221 |
-
B(B&&
|
| 222 |
-
~B()
|
| 223 |
};
|
|
|
|
| 224 |
struct D : public A, public B {
|
| 225 |
-
|
| 226 |
-
//
|
| 227 |
-
//
|
| 228 |
-
//
|
|
|
|
| 229 |
};
|
| 230 |
```
|
| 231 |
|
| 232 |
-
Furthermore, if `A::~A()`
|
| 233 |
-
|
| 234 |
-
|
| 235 |
-
base class
|
| 236 |
-
restrictive as that in the base class.
|
| 237 |
|
| 238 |
-
|
| 239 |
-
explicit *exception-specification* is treated as if it were specified
|
| 240 |
-
with `noexcept(true)`.
|
| 241 |
|
| 242 |
-
An
|
| 243 |
|
| 244 |
- in an expression, the function is the unique lookup result or the
|
| 245 |
selected member of a set of overloaded functions ([[basic.lookup]],
|
| 246 |
[[over.match]], [[over.over]]);
|
| 247 |
- the function is odr-used ([[basic.def.odr]]) or, if it appears in an
|
| 248 |
unevaluated operand, would be odr-used if the expression were
|
| 249 |
potentially-evaluated;
|
| 250 |
-
- the
|
| 251 |
-
|
| 252 |
-
function);
|
| 253 |
- the function is defined; or
|
| 254 |
-
- the
|
| 255 |
-
function that calls the function. A defaulted declaration
|
| 256 |
-
require the
|
| 257 |
-
evaluated until the implicit
|
| 258 |
-
function is needed, but an explicit *
|
| 259 |
-
the implicit
|
|
|
|
| 260 |
|
| 261 |
-
The
|
| 262 |
evaluated as described above only when needed; similarly, the
|
| 263 |
-
*
|
| 264 |
member function of a class template is instantiated only when needed.
|
| 265 |
|
| 266 |
-
In a *dynamic-exception-specification*, a *type-id* followed by an
|
| 267 |
-
ellipsis is a pack expansion ([[temp.variadic]]).
|
| 268 |
-
|
| 269 |
-
The use of *dynamic-exception-specification*s is deprecated (see Annex
|
| 270 |
-
[[depr]]).
|
| 271 |
-
|
|
|
|
| 1 |
## Exception specifications <a id="except.spec">[[except.spec]]</a>
|
| 2 |
|
| 3 |
+
The predicate indicating whether a function cannot exit via an exception
|
| 4 |
+
is called the *exception specification* of the function. If the
|
| 5 |
+
predicate is false, the function has a *potentially-throwing exception
|
| 6 |
+
specification*, otherwise it has a *non-throwing exception
|
| 7 |
+
specification*. The exception specification is either defined
|
| 8 |
+
implicitly, or defined explicitly by using a *noexcept-specifier* as a
|
| 9 |
+
suffix of a function declarator ([[dcl.fct]]).
|
| 10 |
|
| 11 |
``` bnf
|
| 12 |
+
noexcept-specifier:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 13 |
'noexcept' '(' constant-expression ')'
|
| 14 |
'noexcept'
|
| 15 |
+
'throw' '(' ')'
|
| 16 |
```
|
| 17 |
|
| 18 |
+
In a *noexcept-specifier*, the *constant-expression*, if supplied, shall
|
| 19 |
+
be a contextually converted constant expression of type `bool` (
|
| 20 |
+
[[expr.const]]); that constant expression is the exception specification
|
| 21 |
+
of the function type in which the *noexcept-specifier* appears. A `(`
|
| 22 |
+
token that follows `noexcept` is part of the *noexcept-specifier* and
|
| 23 |
+
does not commence an initializer ([[dcl.init]]). The
|
| 24 |
+
*noexcept-specifier* `noexcept` without a *constant-expression* is
|
| 25 |
+
equivalent to the *noexcept-specifier* `noexcept(true)`. The
|
| 26 |
+
*noexcept-specifier* `throw()` is deprecated ([[depr.except.spec]]),
|
| 27 |
+
and equivalent to the *noexcept-specifier* `noexcept(true)`.
|
| 28 |
+
|
| 29 |
+
If a declaration of a function does not have a *noexcept-specifier*, the
|
| 30 |
+
declaration has a potentially throwing exception specification unless it
|
| 31 |
+
is a destructor or a deallocation function or is defaulted on its first
|
| 32 |
+
declaration, in which cases the exception specfication is as specified
|
| 33 |
+
below and no other declaration for that function shall have a
|
| 34 |
+
*noexcept-specifier*. In an explicit instantiation ([[temp.explicit]])
|
| 35 |
+
a *noexcept-specifier* may be specified, but is not required. If a
|
| 36 |
+
*noexcept-specifier* is specified in an explicit instantiation
|
| 37 |
+
directive, the exception specification shall be the same as the
|
| 38 |
+
exception specification of all other declarations of that function. A
|
| 39 |
+
diagnostic is required only if the exception specifications are not the
|
| 40 |
+
same within a single translation unit.
|
| 41 |
+
|
| 42 |
+
If a virtual function has a non-throwing exception specification, all
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 43 |
declarations, including the definition, of any function that overrides
|
| 44 |
+
that virtual function in any derived class shall have a non-throwing
|
| 45 |
+
exception specification, unless the overriding function is defined as
|
| 46 |
+
deleted.
|
| 47 |
+
|
| 48 |
+
[*Example 1*:
|
| 49 |
|
| 50 |
``` cpp
|
| 51 |
struct B {
|
| 52 |
+
virtual void f() noexcept;
|
| 53 |
virtual void g();
|
| 54 |
+
virtual void h() noexcept = delete;
|
| 55 |
};
|
| 56 |
|
| 57 |
struct D: B {
|
| 58 |
void f(); // ill-formed
|
| 59 |
+
void g() noexcept; // OK
|
| 60 |
+
void h() = delete; // OK
|
| 61 |
};
|
| 62 |
```
|
| 63 |
|
| 64 |
+
The declaration of `D::f` is ill-formed because it has a
|
| 65 |
+
potentially-throwing exception specification, whereas `B::f` has a
|
| 66 |
+
non-throwing exception specification.
|
|
|
|
|
|
|
|
|
|
| 67 |
|
| 68 |
+
— *end example*]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 69 |
|
| 70 |
Whenever an exception is thrown and the search for a handler (
|
| 71 |
+
[[except.handle]]) encounters the outermost block of a function with a
|
| 72 |
+
non-throwing exception specification, the function `std::terminate()` is
|
| 73 |
+
called ([[except.terminate]]).
|
| 74 |
|
| 75 |
+
[*Note 1*: An implementation shall not reject an expression merely
|
| 76 |
+
because, when executed, it throws or might throw an exception from a
|
| 77 |
+
function with a non-throwing exception specification. — *end note*]
|
| 78 |
+
|
| 79 |
+
[*Example 2*:
|
| 80 |
|
| 81 |
``` cpp
|
| 82 |
+
extern void f(); // potentially-throwing
|
|
|
|
|
|
|
|
|
|
| 83 |
|
| 84 |
+
void g() noexcept {
|
| 85 |
+
f(); // valid, even if f throws
|
| 86 |
+
throw 42; // valid, effectively a call to std::terminate
|
|
|
|
|
|
|
| 87 |
}
|
| 88 |
```
|
| 89 |
|
| 90 |
+
The call to `f` is well-formed even though, when called, `f` might throw
|
| 91 |
+
an exception.
|
|
|
|
| 92 |
|
| 93 |
+
— *end example*]
|
|
|
|
|
|
|
|
|
|
|
|
|
| 94 |
|
| 95 |
+
An expression `e` is *potentially-throwing* if
|
|
|
|
|
|
|
| 96 |
|
| 97 |
+
- `e` is a function call ([[expr.call]]) whose *postfix-expression* has
|
| 98 |
+
a function type, or a pointer-to-function type, with a
|
| 99 |
+
potentially-throwing exception specification, or
|
| 100 |
+
- `e` implicitly invokes a function (such as an overloaded operator, an
|
| 101 |
+
allocation function in a *new-expression*, a constructor for a
|
| 102 |
+
function argument, or a destructor if `e` is a full-expression (
|
| 103 |
+
[[intro.execution]])) that is potentially-throwing, or
|
| 104 |
+
- `e` is a *throw-expression* ([[expr.throw]]), or
|
| 105 |
+
- `e` is a `dynamic_cast` expression that casts to a reference type and
|
| 106 |
+
requires a runtime check ([[expr.dynamic.cast]]), or
|
| 107 |
+
- `e` is a `typeid` expression applied to a (possibly parenthesized)
|
| 108 |
+
built-in unary `*` operator applied to a pointer to a polymorphic
|
| 109 |
+
class type ([[expr.typeid]]), or
|
| 110 |
+
- any of the immediate subexpressions ([[intro.execution]]) of `e` is
|
| 111 |
+
potentially-throwing.
|
| 112 |
|
| 113 |
+
An implicitly-declared constructor for a class `X`, or a constructor
|
| 114 |
+
without a *noexcept-specifier* that is defaulted on its first
|
| 115 |
+
declaration, has a potentially-throwing exception specification if and
|
| 116 |
+
only if any of the following constructs is potentially-throwing:
|
| 117 |
+
|
| 118 |
+
- a constructor selected by overload resolution in the implicit
|
| 119 |
+
definition of the constructor for class `X` to initialize a
|
| 120 |
+
potentially constructed subobject, or
|
| 121 |
+
- a subexpression of such an initialization, such as a default argument
|
| 122 |
+
expression, or,
|
| 123 |
+
- for a default constructor, a default member initializer.
|
| 124 |
+
|
| 125 |
+
[*Note 2*: Even though destructors for fully-constructed subobjects are
|
| 126 |
+
invoked when an exception is thrown during the execution of a
|
| 127 |
+
constructor ([[except.ctor]]), their exception specifications do not
|
| 128 |
+
contribute to the exception specification of the constructor, because an
|
| 129 |
+
exception thrown from such a destructor would call `std::terminate`
|
| 130 |
+
rather than escape the constructor ([[except.throw]],
|
| 131 |
+
[[except.terminate]]). — *end note*]
|
| 132 |
|
| 133 |
+
The exception specification for an implicitly-declared destructor, or a
|
| 134 |
+
destructor without a *noexcept-specifier*, is potentially-throwing if
|
| 135 |
+
and only if any of the destructors for any of its potentially
|
| 136 |
+
constructed subojects is potentially throwing.
|
| 137 |
|
| 138 |
+
The exception specification for an implicitly-declared assignment
|
| 139 |
+
operator, or an assignment-operator without a *noexcept-specifier* that
|
| 140 |
+
is defaulted on its first declaration, is potentially-throwing if and
|
| 141 |
+
only if the invocation of any assignment operator in the implicit
|
| 142 |
+
definition is potentially-throwing.
|
|
|
|
|
|
|
|
|
|
| 143 |
|
| 144 |
+
A deallocation function ([[basic.stc.dynamic.deallocation]]) with no
|
| 145 |
+
explicit *noexcept-specifier* has a non-throwing exception
|
| 146 |
+
specification.
|
| 147 |
|
| 148 |
+
[*Example 3*:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 149 |
|
| 150 |
``` cpp
|
| 151 |
struct A {
|
| 152 |
+
A(int = (A(5), 0)) noexcept;
|
| 153 |
+
A(const A&) noexcept;
|
| 154 |
+
A(A&&) noexcept;
|
| 155 |
+
~A();
|
| 156 |
};
|
| 157 |
struct B {
|
| 158 |
B() throw();
|
| 159 |
+
B(const B&) = default; // implicit exception specification is noexcept(true)
|
| 160 |
+
B(B&&, int = (throw Y(), 0)) noexcept;
|
| 161 |
+
~B() noexcept(false);
|
| 162 |
};
|
| 163 |
+
int n = 7;
|
| 164 |
struct D : public A, public B {
|
| 165 |
+
int * p = new int[n];
|
| 166 |
+
// D::D() potentially-throwing, as the new operator may throw bad_alloc or bad_array_new_length
|
| 167 |
+
// D::D(const D&) non-throwing
|
| 168 |
+
// D::D(D&&) potentially-throwing, as the default argument for B's constructor may throw
|
| 169 |
+
// D::~D() potentially-throwing
|
| 170 |
};
|
| 171 |
```
|
| 172 |
|
| 173 |
+
Furthermore, if `A::~A()` were virtual, the program would be ill-formed
|
| 174 |
+
since a function that overrides a virtual function from a base class
|
| 175 |
+
shall not have a potentially-throwing exception specification if the
|
| 176 |
+
base class function has a non-throwing exception specification.
|
|
|
|
| 177 |
|
| 178 |
+
— *end example*]
|
|
|
|
|
|
|
| 179 |
|
| 180 |
+
An exception specification is considered to be *needed* when:
|
| 181 |
|
| 182 |
- in an expression, the function is the unique lookup result or the
|
| 183 |
selected member of a set of overloaded functions ([[basic.lookup]],
|
| 184 |
[[over.match]], [[over.over]]);
|
| 185 |
- the function is odr-used ([[basic.def.odr]]) or, if it appears in an
|
| 186 |
unevaluated operand, would be odr-used if the expression were
|
| 187 |
potentially-evaluated;
|
| 188 |
+
- the exception specification is compared to that of another declaration
|
| 189 |
+
(e.g., an explicit specialization or an overriding virtual function);
|
|
|
|
| 190 |
- the function is defined; or
|
| 191 |
+
- the exception specification is needed for a defaulted special member
|
| 192 |
+
function that calls the function. \[*Note 3*: A defaulted declaration
|
| 193 |
+
does not require the exception specification of a base member function
|
| 194 |
+
to be evaluated until the implicit exception specification of the
|
| 195 |
+
derived function is needed, but an explicit *noexcept-specifier* needs
|
| 196 |
+
the implicit exception specification to compare
|
| 197 |
+
against. — *end note*]
|
| 198 |
|
| 199 |
+
The exception specification of a defaulted special member function is
|
| 200 |
evaluated as described above only when needed; similarly, the
|
| 201 |
+
*noexcept-specifier* of a specialization of a function template or
|
| 202 |
member function of a class template is instantiated only when needed.
|
| 203 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|