1
votes

Please forgive my C++ naiveté

I was thinking of creating Exception classes that would inherit from std::stringstream so that I could use stringstream’s operator << to build up text error messages while at the same time being able to try catch the exceptions by type.

My code is something like

class ExceptionXYZ : public std::stringstream
{};

Void someFunction()
{
   try
   {
      //do something
   }
   catch(const ExceptionXYZ& e)
   {
      //handle XYZ
   }

Unfortunately my VS2008 compiler doesn’t like this and complains that

error C2248: 'std::basic_ios<_Elem,_Traits>::basic_ios' : cannot access private member declared in class 'std::basic_ios<_Elem,_Traits>'

basic_ios is a great grandparent (or thereabouts) of stringstream and there must be some implicit access violation somewhere, but between my extremely rusty C++ and the compiler’s unhelpful error message (it doesn’t tell me what private member it’s worried about) I’m a bit lost.

I imagine people do this kind of thing all the time (i.e. throw exceptions with text that have to be caught by type).

Help would be greatly appreciated

3
I can't understand why you would want to do this. Can you explain your use case? - Joseph Mansfield
Which line does the error occur on? - Vaughn Cato

3 Answers

2
votes

You shouldn't inherit from stream classes just to use them during construction. If you really need to build up the error message you might choose to rather store the information needed to build it upon request or build it up on construction.

From the sounds of it you want to do something like this:

throw ExceptionXYZ() << "some " << information << " or " << other;

That's not going to work too well anyway because the operator<<() would all return std::ostream& rather than the exception object you'd want.

0
votes

(Most) types in the STD are designed to not be used as base classes. Only use them as member variables.

To give a message to your exception you could do something like this:

class ExceptionXYZ
{
public:
   ExceptionXYZ(const std::string& msg) : msg_(msg) {}
   const std::string& get_message() const { return msg_; }
private:
   std::string msg_;
};

std::stringstream ss;
ss << "Error " << 42;
throw ExceptionXYZ(ss.str());
0
votes

You cannot use a std::stringstream as a base class for exception because you cannot copy or move a stringstream (because of the streambuffer inside if you have a look at the error message) and that is a requirement for an object to be thrown. So it cannot compile when I do this kind of code:

class ExceptionXYZ : public std::stringstream {};

void test_except() throw (ExceptionXYZ)
{
  ExceptionXYZ xyz;

  xyz << "This exception is useless";
  throw xyz;
}

http://ideone.com/NQUunh