流式传输到异常类

Gra*_*eme 4 c++ operator-overloading

我有一个Exception基类,它定义了一个流函数:

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

我有一个自由函数重载运算符<<:

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

我也有异常重载operator <<:

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

我这样使用它:

else {
    throw CoffeeException() << "Exception text";
}
Run Code Online (Sandbox Code Playgroud)

当我尝试使用该类时,编译器没有看到该函数,它只是建议标准流操作符可用但不记录我的Exception或CoffeeException免费函数.这种实现看起来是否正确?

Jam*_*nze 8

它看起来像尝试将临时引用绑定到非const引用的常见问题. CoffeeException() << "Exception text"不能绑定你operator<<,因为CoffeeException()是暂时的.只需成为您operator<<的会员:

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

虽然我很喜欢它:你绝对不希望reinterpret_cast它结束Exception::stream.使用此强制转换的结果是未定义的行为.它通常在单继承的情况下工作,但在涉及多继承的情况下失败(但即使这样也不能保证).最简单的解决方案是我上面所做的(并 Exception::stream返回void); 或者,static_cast 在这里使用(如果在实例化时定义了继承,则应该是合法的).