C++ 如何支持在C+;中的异常处理宏中使用流+;?

C++ 如何支持在C+;中的异常处理宏中使用流+;?,c++,exception,error-handling,macros,C++,Exception,Error Handling,Macros,我有一个小错误函数,如下所示: template<typename ErrorType> void throwError(const std::string &file, const std::string &function, unsigned int line, const std::string &msg = "

我有一个小错误函数,如下所示:

    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());
    }
但是,当我想在错误消息中添加额外信息时,例如数字的值,这是非常不方便的

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

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

LOGIC_ERROR(“您做了一个错误的操作,因为条件\”)如果您愿意稍微更改语法,则可以使用一个简单的helper宏。给定您当前的函数模板

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());
}
模板
void-throwerr(const-std::字符串和文件,
常量std::字符串和函数,
无符号整数行,
const std::string&msg=“”)
{
标准:ostringstream ERRMG;

errMsg我建议一个不同的选项:


这种方法的缺点是,如果格式字符串无效,
fmt::format
将引发异常。您可以在编译时使用
fmt\u string()
宏检查它:

#define LOGIC_ERROR(string) \
    throwError<std::logic_error>(__FILE__, __func__, __LINE__, string)

#define LOGIC_ERROR_P(string, ...) \
    throwError<std::logic_error>(__FILE__, __func__, __LINE__, \
    fmt::format(FMT_STRING(string), __VA_ARGS__))
#定义逻辑错误(字符串)\
抛出器(文件、函数、行、字符串)
#定义逻辑错误(字符串,…)\
抛掷器(uuuu文件uuu,uuuu函数uuu,uuu线uuu\
格式(fmt_字符串(STRING),uu VA_参数)

在这里,我创建了两个版本的
LOGIC\u ERROR
,有和没有额外的参数。根据参数的数量,这两个版本之间可以有一个宏分派,但这留给读者作为练习。

您可以使用
std::to\u string()
将条件转换为字符串,并使用
+
运算符将分段字符串连接为一个字符串。
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";
#define LOGIC_ERROR(...) \
    throwError<std::logic_error>(__FILE__, __func__, __LINE__, fmt::format(__VA_ARGS__))
if (condition == bad)
    LOGIC_ERROR("you did a bad because condition {} != {}", condition, bad);
#define LOGIC_ERROR(string) \
    throwError<std::logic_error>(__FILE__, __func__, __LINE__, string)

#define LOGIC_ERROR_P(string, ...) \
    throwError<std::logic_error>(__FILE__, __func__, __LINE__, \
    fmt::format(FMT_STRING(string), __VA_ARGS__))