template based exception class

N

Nick Keighley

Hi,

Perhaps I was little ambitious with this template class.

When I define exception classes for packages I seemed to write code
similar to this each time:-

class DecompressionError : public std::runtime_error
{
public:
DecompressionError (const std::string& what = "")
: runtime_error(std::string("Decompression Error ") + what)
{
}

virtual ~DecompressionError()
{
}
};


Any comments on the wisdom of such a class?

This looked like a good use for templates. Hence:-

#include <string>
#include <stdexcept>

template class<const char* NAME> class Error: public std::runtime_error
// line 19
{
public:

Error (const std::string& what = "")
: runtime_error(std::string(NAME) + " Error ") + what)
{

}



virtual ~Error()
{

}

};


int main (void)
{
Error ("Pippo") pippo_x;

try
{
throw Error("Pippo");
}
catch (Error ("Pippo")& e)
{
cerr << e.what();
}
}


This actually crashed the compiler!

:\bin\error_templ.cpp(19) : fatal error C1001: INTERNAL COMPILER ERROR
(compiler file 'msc1.cpp', line 1188)
Please choose the Technical Support command on the Visual C++
Help menu, or open the Technical Support help file for more
information


So does my code look ok?


--
Nick Keighley

Programming should never be boring, because anything
mundane and repetitive should be done by the computer.
~Alan Turing
 
M

Morten V Pedersen

Nick said:
Hi,

Perhaps I was little ambitious with this template class.

When I define exception classes for packages I seemed to write code
similar to this each time:-

class DecompressionError : public std::runtime_error
{
public:
DecompressionError (const std::string& what = "")
: runtime_error(std::string("Decompression Error ") + what)
{
}

virtual ~DecompressionError()
{
}
};


Any comments on the wisdom of such a class?

This looked like a good use for templates. Hence:-

#include <string>
#include <stdexcept>

template class<const char* NAME> class Error: public std::runtime_error
// line 19
{
public:

Error (const std::string& what = "")
: runtime_error(std::string(NAME) + " Error ") + what)
{

}



virtual ~Error()
{

}

};


int main (void)
{
Error ("Pippo") pippo_x;

try
{
throw Error("Pippo");
}
catch (Error ("Pippo")& e)
{
cerr << e.what();
}
}


This actually crashed the compiler!

:\bin\error_templ.cpp(19) : fatal error C1001: INTERNAL COMPILER ERROR
(compiler file 'msc1.cpp', line 1188)
Please choose the Technical Support command on the Visual C++
Help menu, or open the Technical Support help file for more
information


So does my code look ok?


--
Nick Keighley

Programming should never be boring, because anything
mundane and repetitive should be done by the computer.
~Alan Turing

Hi Nick,
I have a couple of quick comments to your code:
- Check: http://www.comeaucomputing.com/techtalk/templates/#stringliteral
- template class<const char* NAME> => template<const char* NAME>
- You also need to check you angle brackets vs. parantheses

// morten
 
S

Stephane Wirtel

And why not:

#define STRINGIZE(x) XSTRING(x)
#define XSTRING(x) #x

#define DECLARE_EXCEPTION(name) \
class name##Exception : public std::runtime_error { \
public: \
name##Exception( const std::string & what = "" ) \
: std::runtime_error( std::string(STRINGIZE(name) "Exception") + (
what.empty() ? std::string("") : std::string(" : ")) + what ) { \
} \
virtual ~name##Exception() throw() { \
} \
}

DECLARE_EXCEPTION(My);
DECLARE_EXCEPTION(Super);

int main( int argc, char ** argv ) {
try {
throw MyException("There is an error");
}
catch( const MyException & ex ) {
std::cerr << ex.what() << std::endl;
}
return 0;
}
 
N

Nick Keighley

Stephane Wirtel wrote:

you snipped my original question
And why not:

#define STRINGIZE(x) XSTRING(x)
#define XSTRING(x) #x

#define DECLARE_EXCEPTION(name) \
class name##Exception : public std::runtime_error { \
public: \
name##Exception( const std::string & what = "" ) \
: std::runtime_error( std::string(STRINGIZE(name) "Exception") + (
what.empty() ? std::string("") : std::string(" : ")) + what ) { \
} \
virtual ~name##Exception() throw() { \
} \
}

DECLARE_EXCEPTION(My);
DECLARE_EXCEPTION(Super);

int main( int argc, char ** argv ) {
try {
throw MyException("There is an error");
}
catch( const MyException & ex ) {
std::cerr << ex.what() << std::endl;
}
return 0;
}

yeah, I know I could have done that. But I thought the idea generally
was
to replace function type macros with templates.
 
S

Stephane Wirtel

yeah, I know I could have done that. But I thought the idea generally
was
to replace function type macros with templates.
Why do you want to use the template for this case ?

The template parameters cannot be 'double' or 'char *'.
 
N

Nick Keighley

Morten said:
Nick Keighley wrote:

I have a couple of quick comments to your code:
- Check: http://www.comeaucomputing.com/techtalk/templates/#stringliteral

ah! and he became Enlightened

- template class<const char* NAME> => template<const char* NAME>

I've no idea where that extra "class" came from...
- You also need to check you angle brackets vs. parantheses

sure do!

excellent! comp.lang.c++ is worth every penny I pay for it!

This code:-

************************************************************************
#include <string>
#include <stdexcept>
#include <iostream>

char x_name[] = "Pippo";


template <const char* NAME> class Error: public std::runtime_error
{
public:

Error (const std::string& what = "")
: runtime_error(std::string(NAME) + " Error " + what)
{

}



virtual ~Error()
{

}

};


int main (void)
{
Error <x_name> pippo_x;

try
{
throw Error<x_name>("frodo");
}
catch (Error <x_name>& e)
{
std::cerr << e.what();
}

return 0;
}

************************************************************************
produces this output:-
Pippo Error frodo


--
Nick Keighley

- I wanted to put a check in getGuiExtract(), but it's a void
method, inherited from the father of the father of the father of
the
father of the father of the father of the father of the father...

So I can't modify its interface.
[found in code comment]
 
N

Nick Keighley

Stephane Wirtel wrote:

I tried to pass a string constant as a macro parameter. Stephane
suggested
a macro instead
Why do you want to use the template for this case ?

to avoid writing the same code (admittedly not very much) over and over
again.

The template parameters cannot be 'double' or 'char *'.

why would I want it to be double? Why can't it be double. I agree
the template version looks so awkward I'll probably use the macro
 
S

Stephane Wirtel

I tried to pass a string constant as a macro parameter. Stephane
suggested
a macro instead
There is a trick if you want to use 'char *' in the template parameter,
you can define a string as like as an 'extern char []'.

But you can get an error with this example:

extern const char hello [] = "hello";
extern const char world [] = "world";

the variable 'hello' and 'world' are const char [6] ( with '\0' )

my_template< hello > template_hello;
my_template< world > template_world;

for the compiler is the same type.
why would I want it to be double? Why can't it be double. I agree
the template version looks so awkward I'll probably use the macro

double and char * are the only cases where you can't use these types for a
template parameter.
If you are interested by the template, you can read "C++ Template : The
complete guide" of Vandervoorde & Josuttis.

Stephane
 
J

jimmy

Nick Keighley 写é“:
Morten said:
Nick Keighley wrote:

I have a couple of quick comments to your code:
- Check: http://www.comeaucomputing.com/techtalk/templates/#stringliteral

ah! and he became Enlightened

- template class<const char* NAME> => template<const char* NAME>

I've no idea where that extra "class" came from...
- You also need to check you angle brackets vs. parantheses

sure do!

excellent! comp.lang.c++ is worth every penny I pay for it!

This code:-

************************************************************************
#include <string>
#include <stdexcept>
#include <iostream>

char x_name[] = "Pippo";


template <const char* NAME> class Error: public std::runtime_error
{
public:

Error (const std::string& what = "")
: runtime_error(std::string(NAME) + " Error " + what)
{

}



virtual ~Error()
{

}

};


int main (void)
{
Error <x_name> pippo_x;

try
{
throw Error<x_name>("frodo");
}
catch (Error <x_name>& e)
{
std::cerr << e.what();
}

return 0;
}

************************************************************************
produces this output:-
Pippo Error frodo


--
Nick Keighley

- I wanted to put a check in getGuiExtract(), but it's a void
method, inherited from the father of the father of the father of
the
father of the father of the father of the father of the father...

So I can't modify its interface.
[found in code comment]
you simply go insane.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,236
Members
46,825
Latest member
VernonQuy6

Latest Threads

Top