Stream to exception class

I have an Exception base class that defines a stream function:

class Exception { public: template <typename TData, typename TException> TException& stream(const TData& data) { stream_ << data; return *reinterpret_cast<TException*>(this); } }; 

I have a free function overload operator <:

 template <typename TData> Exception& operator<<(Exception& ex, const TData& data) { return ex.stream<TData, Exception>(data); } 

I also have an exception exception overload operator <:

 template <typename TData> CoffeeException& operator<<(CoffeeException& ex, const TData& data) { return ex.stream<TData, CoffeeException>(data); } 

I use it like this:

 else { throw CoffeeException() << "Exception text"; } 

When I try to use a class, the compiler does not see this function, it just offers the standard flow operators available, but does not notice that my Exception or CoffeeException functions are free. Does this implementation look right?

+4
source share
2 answers

It seems that usually there is a problem with linking temporary to non-constant link. CoffeeException() << "Exception text" cannot be bound to your operator<< because CoffeeException() is temporary. Just make your operator<< member:

 class CoffeeException : public Exception { // ... public: template <typename TData> CoffeeException& operator<<( TData const& data ) { stream( data ); return *this; } }; 

While I am: you definitely do not want reinterpret_cast to end with Exception::stream . Using the results of this cast, undefined behavior. It usually works in cases of single inheritance, but fail when multiple inheritance is involved (but even this is not guaranteed). The simplest solution is what I did above (and Exception::stream return void ); alternatively, use static_cast here (which should be legal if inheritance is defined at the instance point).

+8
source
 CoffeeException& operator<<(const CoffeeException& ex, const TData& data); 

This link must be const because you are trying to pass an unnamed object. You can also create a temporary object to avoid using the const reference.

-1
source

Source: https://habr.com/ru/post/1401614/


All Articles