I am opening an issue, as part of resolving this will be adding the results of the 'what' function for each class below to the index of implementation defined behavior. However, before looking into that, I want to ensure a consistent presentation of these classes with essentially the same behavior.
bad_alloc
bad_array_new_length
bad_cast
bad_exception
bad_function_call
bad_typeid
bad_weak_ptr
At one extreme, we have the specification for the original bad_* classes:
class bad_alloc : public exception {
public:
bad_alloc() noexcept;
bad_alloc(const bad_alloc&) noexcept;
bad_alloc& operator=(const bad_alloc&) noexcept;
virtual const char* what() const noexcept;
};
At the other, we have the specification for the exceptions adopted via TR1:
class bad_weak_ptr: public std::exception {
public:
bad_weak_ptr() noexcept;
};
Note that an override of 'what' is assumed, but not declared, with the specification for 'what' buried in the contract of the default constructor.
My preferred formulation would be:
struct bad_exception : exception {
const char* what() const noexcept override;
};
This strips out the redundant exceptions and assignment operators, which will be implicitly declared/defined with 'noexcept' specifier. It uses 'struct' as defaulting everything to public access simplifies further, and finally adds the 'override' qualifier to 'what', for completeness. As this involves a change of normative wording, I believe it would require an LWG issue to resolve.
Failing that, I would prefer to consistently apply the 'bad_alloc' format above, where everything is called out explicitly. In both cases, we get a 'what' function in the index that can be linked to the index of implementation defined behavior.
I am opening an issue, as part of resolving this will be adding the results of the 'what' function for each class below to the index of implementation defined behavior. However, before looking into that, I want to ensure a consistent presentation of these classes with essentially the same behavior.
bad_alloc
bad_array_new_length
bad_cast
bad_exception
bad_function_call
bad_typeid
bad_weak_ptr
At one extreme, we have the specification for the original bad_* classes:
class bad_alloc : public exception {
public:
bad_alloc() noexcept;
bad_alloc(const bad_alloc&) noexcept;
bad_alloc& operator=(const bad_alloc&) noexcept;
virtual const char* what() const noexcept;
};
At the other, we have the specification for the exceptions adopted via TR1:
class bad_weak_ptr: public std::exception {
public:
bad_weak_ptr() noexcept;
};
Note that an override of 'what' is assumed, but not declared, with the specification for 'what' buried in the contract of the default constructor.
My preferred formulation would be:
struct bad_exception : exception {
const char* what() const noexcept override;
};
This strips out the redundant exceptions and assignment operators, which will be implicitly declared/defined with 'noexcept' specifier. It uses 'struct' as defaulting everything to public access simplifies further, and finally adds the 'override' qualifier to 'what', for completeness. As this involves a change of normative wording, I believe it would require an LWG issue to resolve.
Failing that, I would prefer to consistently apply the 'bad_alloc' format above, where everything is called out explicitly. In both cases, we get a 'what' function in the index that can be linked to the index of implementation defined behavior.