0

I'm making a simple Error class that should be thrown using throw statement, logged or written in console. The basic idea of the usage is:

//const char* filename is function argument
if(!file_exists(filename))
  throw Error(line, file, severity)<<"Invalid argument: the file does not exist: "<<filename;

I originally wanted to extend stringstream, but my searches indicate that it's impossible to extend on streams.

I'd really like to make the error class as convenient as you can see above, which means able to "eat" various types and append them to internal error message.

Community
  • 1
  • 1

1 Answers1

2

So actually it's not so hard. You can't inherit from stringstream directly - or I just didn't find out how. You'll soon drown in std template system...

template<class _Elem,
class _Traits,
class _Alloc>
// ... mom help me!

But, you can make a template:

template <class T>
Error& Error::operator<<(T const& value) {
    //private std::stringstream message
    message<<value;
    //You can also trigger code for every call - neat, ain't it? 
}

You'll be adding all values from this method to private variable within the class:

class Error
{
public:
    Error(int, const char*, int);
    ~Error(void);
    std::string file;
    unsigned int line;
    //Returns message.str()
    std::string what();
    //Calls message.operator<<()
    template <class T>
    Error& operator<< (T const& rhs);

private: 
    std::stringstream message;

};

There's still something I'm missing - how to distinguish between types supported by stringstream and others and throw error on the line of call, rather than in Error class. Also I'd like to write own handlers for unsupported types.

  • What do you mean? This won't compile if `T` doesn't support `operator< – wakjah Dec 08 '14 at 23:55
  • @wakjah It's just that it won't compile and will act like the error was in `Error.cpp` - not in the caller code. As of other overloads, I'll need to look up how templates work... – Tomáš Zato - Reinstate Monica Dec 09 '14 at 00:05
  • 1
    Yes, template errors take a bit of getting used to. But you should just let the compiler do its job and emit the error. The alternative would be to implement a SFINAE check and use `static_assert` (e.g., see [this thread](http://stackoverflow.com/questions/5768511/using-sfinae-to-check-for-global-operator)), but it's very difficult to get a solution that covers all cases, so if I were you I'd just let the compiler do its job, which will cover all cases. Or wait for concepts to be implemented in your favourite environment :) – wakjah Dec 09 '14 at 00:13
  • 2
    `You can't inherit from stringstream directly` Sure you can, the issue is that streams can't be copied so you can't throw one. – user657267 Dec 09 '14 at 00:18