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__))