首页 > 解决方案 > 如何支持在 C++ 的异常处理宏中使用流?

问题描述

我有一个看起来像这样的小错误函数:

    template<typename ErrorType>
    void throwError(const std::string &file,
                    const std::string &function,
                    unsigned int line,
                    const std::string &msg = "") {
        std::ostringstream errMsg;
        errMsg << file << ":" << line << ":" << function << ":"
               << "\nError: " << msg << std::endl;
        std::cerr << errMsg.str();
        throw ErrorType(errMsg.str());
    }

然后我有一些使用该函数的宏:

#define INVALID_ARGUMENT_ERROR(msg) throwError<std::invalid_argument>(__FILE__, __func__, __LINE__, msg)
#define LOGIC_ERROR(msg) throwError<std::logic_error>(__FILE__, __func__, __LINE__, msg)

所以我可以这样做:

if (condition == bad)
    LOGIC_ERROR("you did a bad");

但是,当我想在错误消息中添加其他信息(例如数字值)时,这非常不方便。

修改此函数以使我能够使用流而不是字符串的好方法是什么?所以我希望能够做到:

if (condition == bad)
    LOGIC_ERROR("you did a bad because condition \"" << condition << " != " << bad);

我尝试将其更改为std::string string msg不起作用std::ostringstream

标签: c++exceptionerror-handlingmacros

解决方案


如果您愿意稍微更改语法,则可以使用简单的辅助宏。鉴于您当前的功能模板...

template<typename ErrorType>
void throwError(const std::string &file,
                const std::string &function,
                unsigned int line,
                const std::string &msg = "")
{
    std::ostringstream errMsg;
    errMsg << file << ":" << line << ":" << function << ":"
           << "\nError: " << msg << std::endl;
    std::cerr << errMsg.str();
    throw ErrorType(errMsg.str());
}

然后你可以定义...

#define THROW_HELPER(ex_type)                                           \
    for (std::stringstream ss; true; throwError<ex_type>(__FILE__, __func__, __LINE__, ss.str())) \
        ss

#define INVALID_ARGUMENT_ERROR THROW_HELPER(std::invalid_argument)
#define LOGIC_ERROR            THROW_HELPER(std::logic_error)

然后这些可以用作,例如..

LOGIC_ERROR << "extra messages go here";

请注意,当前std::stringstream在抛出异常的过程中创建了两个单独的实例,因此显示的代码可能应该“压缩”一点以防止这种情况[留作练习:-)]。


推荐阅读