debugcppMinor
Exception classes
Viewed 0 times
classesexceptionstackoverflow
Problem
This code can be found in the archive here. Usually I have a .cc file, but in this case it's all in a header. Am wondering about that. It needs to work in VS12. If possible I'll post more code from the archive for review. I started with this because it's used a lot. Tia.
Edit - @Loki Astari
I have compile problems on both clang and gcc if I remove the non const version of that function. Clang says there's "no matching function for call to to_string."
IIuc it goes on to say it doesn't like this line:
I ran across that a few months ago and found that adding the non-const version got the compilers to accept it. I'm not sure what the problem is really. I'm using flex and that's where yytext comes from.
Oo Tiib suggested the raise function as a help for debugging -- a central function where you could put a breakpoint to see the stack. It may be something used in some large projects. That made some sense so I decided to try it. I believe I need both versions of raise to avoid slicing.
Edit 2:
Removed raise functions from above code.
#ifndef CMW_ErrorWords_hh
#define CMW_ErrorWords_hh
#include
#include
namespace cmw {
class failure : public ::std::exception {
::std::string whatStr;
public:
explicit failure (char const* what_) : whatStr(what_)
{}
explicit failure (::std::string what_) : whatStr(::std::move(what_))
{}
~failure () throw()
{}
char const* what () const throw()
{ return whatStr.c_str(); }
failure& operator
failure& operator
eof& operator<< (T val)
{
failure::operator<<(val);
return *this;
}
};
}
#endifEdit - @Loki Astari
I have compile problems on both clang and gcc if I remove the non const version of that function. Clang says there's "no matching function for call to to_string."
whatStr.append(::std::to_string(val));IIuc it goes on to say it doesn't like this line:
raise(failure("Blah blah ") << yytext);I ran across that a few months ago and found that adding the non-const version got the compilers to accept it. I'm not sure what the problem is really. I'm using flex and that's where yytext comes from.
Oo Tiib suggested the raise function as a help for debugging -- a central function where you could put a breakpoint to see the stack. It may be something used in some large projects. That made some sense so I decided to try it. I believe I need both versions of raise to avoid slicing.
Edit 2:
Removed raise functions from above code.
Solution
Though std::exception does not have a constructor for taking an error message; the other standard excretions do. So you can make your exception class simpler by inheriting from one of these.
I understand you are trying to make your exceptions easier to use by adding a couple of stream operator to the class. But you can achieve the same affect with greater flexibility using std::stringstream.
If the only difference between a methods is the constness of their parameters. Then the const version is all you need. As it will accept normal values and promise not to change them.
I don't like your raise (and why two different version. Why not raise on the base class of std::exception (that will cover you for all exceptions)).
In my opinion (so its perfectly valid to believe differently) this buys you nothing and makes the code less readable.
class failure : public ::std::runtime_error {
public:
failure (std::string const& msg) : ::std::runtime_error(msg)I understand you are trying to make your exceptions easier to use by adding a couple of stream operator to the class. But you can achieve the same affect with greater flexibility using std::stringstream.
// Your way:
failure x("Hi there");
x << ": More info:" << 5 << " At night:" << 22;
// using string stream (works with all stream-able types)
std::stringstream msg;
msg << "Hi there" << ": More info:" << 5 << " At night:" << 22;
failure y(msg.str());If the only difference between a methods is the constness of their parameters. Then the const version is all you need. As it will accept normal values and promise not to change them.
// This method is not needed
failure& operator<< (char* s)
{
whatStr.append(s);
return *this;
}
// This method will handle both
// `char*` and `char const*` perfectly well.
// if you remove the first method above.
failure& operator<< (char const* s)
{
whatStr.append(s);
return *this;
}I don't like your raise (and why two different version. Why not raise on the base class of std::exception (that will cover you for all exceptions)).
inline void raise (failure const& ex)In my opinion (so its perfectly valid to believe differently) this buys you nothing and makes the code less readable.
raise(failure("hi"));
// Vs
throw failure("Hi");Code Snippets
class failure : public ::std::runtime_error {
public:
failure (std::string const& msg) : ::std::runtime_error(msg)// Your way:
failure x("Hi there");
x << ": More info:" << 5 << " At night:" << 22;
// using string stream (works with all stream-able types)
std::stringstream msg;
msg << "Hi there" << ": More info:" << 5 << " At night:" << 22;
failure y(msg.str());// This method is not needed
failure& operator<< (char* s)
{
whatStr.append(s);
return *this;
}
// This method will handle both
// `char*` and `char const*` perfectly well.
// if you remove the first method above.
failure& operator<< (char const* s)
{
whatStr.append(s);
return *this;
}inline void raise (failure const& ex)raise(failure("hi"));
// Vs
throw failure("Hi");Context
StackExchange Code Review Q#31404, answer score: 4
Revisions (0)
No revisions yet.