Re: Exception base class
On 23 Mrz., 00:20, sp...@pobox.com (Michael Herstine
<sp...@pobox.com>) wrote:
Lars Schouw wrote:
Hi,
I want to construct an exception base class that is easy to use.
Ideally I want to be able to throw exceptions in one liners like this:
throw Exception("string1" + "string2 <number>", 5.0);
I can use boost::format but don't want to use any boost in my code.
Would look like this.. a two liner.
string err = str( boost::format("test %s%") % "some more into");
throw Exception("string1" + "string2 <number>", 5.0);
<snip>
Lars, I do this:
class my_exception: public std::runtime_error
{
public:
// Enumerated list of error codes...
enum Code {
code1, code2, ...
};
// Template struct that just exists to map Code-s to distinct types
template < Code CODE >
struct C {
static const Code x = CODE;
};
// Now I can overload my ctors on the error code
my_exception( const C<code1>&, const std::string &s1,
const std::string &s2, double x );
my_exception( const C<code2>&, int x, int y );
...
};
This lets you throw in one line, albeit at the cost of some ugly
syntax:
throw my_exception( my_exception::C< my_exception::code1 >( ),
"string1", "string2", 5.0 );
but then...
Apart from the rather recommended suggestion to have
a look at the boost.exception library, it doesn't look
like a good idea to me to use the mapping template
as a public API. Instead I would suggest that you define
user-friendly "tag" types, e.g.
struct code1_t{};
struct code2_t{};
....
which constants:
const code1_t code1 = code1_t{};
const code2_t code1 = code2_t{};
which are the API. Then either prepare overloaded
c'tor of your exception class (or provide factory
functions), like so:
my_exception( code1_t, const std::string &s1,
const std::string &s2, double x );
my_exception( code2_t, int x, int y );
...
which are easy to use like this:
throw my_exception( code1, "string1", "string2", 5.0 );
Now what is the template C good for? In fact, you
will probably reduce the risk to assign the wrong
enum value to a given tag type, therefore you define
for internal mapping purposes this template:
template <class>
struct C; // undefined
template <>
struct C<code1_t> {
static const Code x = my_exception::code1;
};
template <>
struct C<code2_t> {
static const Code x = my_exception::code2;
};
....
HTH & Greetings from Bremen,
Daniel Kr?gler
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]