Templated throw() specifications.
Consider this program, which defines a template class who's template
parameter is the type of an exception that can be thrown by members of
the class:
=== BEGIN EXAMPLE ===
#include <iostream>
#include <string>
using namespace std;
void function () throw (string) {
throw string("Oops");
}
template <class EX> class A {
public:
typedef void (* FN) ();
explicit A (FN f) : f_(f) { }
void Call () throw (EX) { f_(); }
private:
FN f_;
};
int main () {
A<string> a(&function);
try {
a.Call();
} catch (const string &s) {
cout << s << endl;
}
}
=== END EXAMPLE ===
The goal of the above is to allow the callback function to throw any
exception it wants (not necessarily derived from std::exception, so
simply specifying that is not an option), and still have the generated
template code for A have the correct throw() specifier for A::Call().
I have a couple of questions:
1. Is having a correct exception specifier even necessary? It's always
been one of those things that C++ has that compilers never seem to
care about (compare to Java, for example, where it is strictly
enforced). VC++ actually generates a compiler warning that throw()
specifiers are ignored, GCC doesn't care, Borland's compiler is the
only one I know of off the top of my head that actually produces
diagnostics when throw() specifications are violated. If it really
doesn't matter (and won't matter in C++0x either), then the above
template stuff is completely unnecessary since I can just declare
Call() with no exception specification at all and not have to deal
with it.
2. If having the correct specification is necessary, is there some
trick I can use to keep you from having to explicitly specify the
exception type template parameter when declaring an A? Some way that I
can make it implicit? In the above program, for example, function() is
declared as throwing a string -- is there some way I can make A<> be
aware of that so I can do "A a(function)" instead of "A<string>
a(function)"? AFAIK function pointer types can't have throw()
information in them so putting it in the A::FN type is not something I
seem to be able to do.
Hopefully this question makes sense; maybe I am thinking about it too
much, but I never really feel comfortable when I throw an exception
from a function that is declared with no exception specifier at all --
plus it's a useful self-documentation tool as well.
Thanks,
Jason