An exception-specification shall appear only on a function declarator for a function type, pointer to function type, reference to function type, or pointer to member function type that is the top-level type of a declaration or definition, or on such a type appearing as a parameter or return type in a function declarator. An exception-specification shall not appear in a typedef declaration or alias-declaration. [ Example:
void f() throw(int); void (*fp)() throw (int); void g(void pfa() throw(int)); typedef int (*pf)() throw(int);
— end example ]
A type denoted in an exception-specification shall not denote an incomplete type or an rvalue reference type. A type denoted in an exception-specification shall not denote a pointer or reference to an incomplete type, other than cv void*. A type cv T, “array of T”, or “function returning T” denoted in an exception-specification is adjusted to type T, “pointer to T”, or “pointer to function returning T”, respectively.
If a virtual function has an exception-specification, all declarations, including the definition, of any function that overrides that virtual function in any derived class shall only allow exceptions that are allowed by the exception-specification of the base class virtual function. [ Example:
struct B { virtual void f() throw (int, double); virtual void g(); }; struct D: B { void f(); void g() throw (int); };
The declaration of D::f is ill-formed because it allows all exceptions, whereas B::f allows only int and double. — end example ] A similar restriction applies to assignment to and initialization of pointers to functions, pointers to member functions, and references to functions: the target entity shall allow at least the exceptions allowed by the source value in the assignment or initialization. [ Example:
class A { }; void (*pf1)(); void (*pf2)() throw(A); void f() { pf1 = pf2; pf2 = pf1; }
— end example ]
An implementation shall not reject an expression merely because when executed it throws or might throw an exception that the containing function does not allow. [ Example:
extern void f() throw(X, Y); void g() throw(X) { f(); }
the call to f is well-formed even though when called, f might throw exception Y that g does not allow. — end example ]
An inheriting constructor ([class.inhctor]) and an implicitly declared special member function (Clause [special]) have an exception-specification. If f is an inheriting constructor or an implicitly declared default constructor, copy constructor, move constructor, destructor, copy assignment operator, or move assignment operator, its implicit exception-specification specifies the type-id T if and only if T is allowed by the exception-specification of a function directly invoked by f's implicit definition; f allows all exceptions if any function it directly invokes allows all exceptions, and f has the exception-specification noexcept(true) if every function it directly invokes allows no exceptions. [ Note: It follows that f has the exception-specification noexcept(true) if it invokes no other functions. — end note ] [ Note: An instantiation of an inheriting constructor template has an implied exception-specification as if it were a non-template inheriting constructor. — end note ] [ Example:
struct A { A(); A(const A&) throw(); A(A&&) throw(); ~A() throw(X); }; struct B { B() throw(); B(const B&) = default; B(B&&) throw(Y); ~B() throw(Y); }; struct D : public A, public B { };
Furthermore, if A::~A() or B::~B() were virtual, D::~D() would not be as restrictive as that of A::~A, and the program would be ill-formed since a function that overrides a virtual function from a base class shall have an exception-specification at least as restrictive as that in the base class. — end example ]
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4