Let's break this down. The declaration:
void virtual func() throw (int, float) = 0;
has 2 constructs that you're asking about. the =0
construct tells the compiler that the declared function is 'abstract', which tells the compiler that the function need not be defined in the class Foo
(though it can be - but it usually isn't) and that an object of class Foo
cannot be directly created - either as a local, global or via new
. However, you can have pointers or references to objects of class Foo
. Some derived class needs to override the function as a non-abstract function - objects of that class can be directly created (as long as there are no other abstract functions that haven't been made 'concrete').
The throw (int, float)
construct is an exception specifification. This tells the compiler that the function's contract is that it will only throw exceptions of type int
or float
if it throws an exception. If the function throws some other kind of exception, the compiler is obligated to handle that specially (by calling std::unexpected()
).
Now, if you try to override that function in a derived class with the following declaration:
void virtual func() throw(short);
You're saying that the function's contract is that it will throw exceptions of type short
if an exception is thrown. However, throwing short
is not part of the contract of the function being overridden, so the compiler doesn't permit it.
If you declare the override like so:
void virtual func() throw(float);
You're saying that the override can throw a float
, which is part of the contract of the original declaration (if it never throws an int
that doesn't break the contract - the original contract only says that the function is allowed to throw an int
, not that it has to).
The relevant part of the standard is 15.4/3 Exception specifications:
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.
Note that the standard explicitly states that an exception specification is not part of the function's type (15.4/12), so a function pointer can, for example, point to functions that have different exception specifications.