问题
I want to custom an Exception class, here's the code:
class TestException : std::exception{
public:
const char *what() const override {
return "TestException";
}
};
I used Clion and the IDE give me a warning on the function what()
:exception specification of overriding function is more lax than base version
But if I build the code with gcc, there's no warning came out. I used c++ 14, gcc 6.5.0
Can anybody help to explain what does the warning mean and can I just ignore it?
回答1:
what from std::exception
is a virtual
function and a virtual
function in a derived class cannot have a laxer exception specification than the function it overrides in the base class.
This is mentioned in the section on "Exception specifications" in the standard.
18.4 Exception specifications [except.spec]
...
4. If a virtual function has a non-throwing exception specification, all declarations, including the definition, of any function that overrides that virtual function in any derived class shall have a non-throwing exception specification, unless the overriding function is defined as deleted.
And the example given (which is somewhat similar to the code in the question) illustrates this as well.
struct B
{
virtual void f() noexcept;
virtual void g();
virtual void h() noexcept = delete;
};
struct D: B
{
void f(); // ill-formed
void g() noexcept; // OK
void h() = delete; // OK
};
The declaration of
D::f
is ill-formed because it has a potentially-throwing exception specification, whereasB::f
has a non-throwing exception specification.
The solution is to change your code like:
class TestException : std::exception{
public:
const char *what() const noexcept override {
return "TestException";
}
};
See compilation here.
回答2:
what
member function of std::exception
is declared as noexcept
since C++11. You should therefore make your overridden what
noexcept
as well. (Actually, this is what the error message says.)
Note that the noexcept
keyword must come before the override
keyword (see, e.g., The order of override and noexcept in the standard for details).
回答3:
The warning you are facing is related to the fact that you are using C++14, if you would compile with C++17 this becomes an error. Hence I would not recommend ignoring it.
Whats going on?
std::exception
defines the method what
as: virtual const char* what() const noexcept;
. You inherit from this method and you re-implement it without specifying noexcept
. By result, you are telling that your implementation can throw exceptions, while the base method indicates this should never throw. (And callers will assume so)
This was fixed in C++17, which made noexcept
part of the type system, and requires you to fix this code:
const char *what() const noexcept override
来源:https://stackoverflow.com/questions/53829852/exception-specification-of-overriding-function-is-more-lax-than-base-version