我想编写一个宏,该宏将std :: ostream&operator
我正在使用GCC 4.1.2(Red Hat 4.1.2-52),并且无法升级它。这是我尝试过的非常精简的版本:#include <sstream>
#include <iostream>
#define ERR_MSG(inputs) errMsg(std::ostringstream().str()) // 1
#define ERR_MSG(inputs) errMsg((std::ostringstream()<<inputs).str()) // 2
<aReturnType> errMsg(const std::string& msg) // use with 1 & 2
{
std::cout << "\nERROR: " << msg << "\n\n";
return <someObjectCreatedBasedOnTheInput>;
}
#define ERR_MSG(inputs) errMsg(std::ostringstream()<<inputs) // 3
<aReturnType> errMsg(const std::ostringstream& msg) // use with 3
{
std::cout << "\nERROR: " << msg.str() << "\n\n";
return <someObjectCreatedBasedOnTheInput>;
}
int main()
{
ERR_MSG("A number: " << 24 << ", a char: " << 'c' << ", that's all!");
}
宏#1可以编译,但是当然只打印“”以外的消息。宏2和3都不编译,但出现以下错误:#define ERR_MSG(inputs) errMsg((std::ostringstream()<<inputs).str()) // 2
error: ‘struct std::basic_ostream<char, std::char_traits<char> >’ has no member named ‘str’
#define ERR_MSG(inputs) errMsg(std::ostringstream()<<inputs) // 3
no matching function for call to ‘errMsg(std::basic_ostream<char, std::char_traits<char> >&)’
note: candidates are: char* errMsg(const std::string&)
note: char* errMsg(const std::ostringstream&)
我对没有宏如何重写它不感兴趣;我自己可以很容易地做到这一点。
===更新:===
我忘了提一下,在其实际用例中,宏调用的函数返回一个可由宏调用者使用的对象。这会使所有无法在单个表达式中实现的宏实现无效,其结果是该宏调用的函数的返回类型。宏的“不执行任何操作”(对于发行版)将简单地将空的std :: string传递给函数,而不管“输入”是什么。对不起,您之前没有提到。
最佳答案
您当前的问题是所有各种operator<<
函数都返回一个ostream&
,而不是一个ostringstream&
。您可以使用a simple cast解决该问题:
#define ERR_MSG(inputs) errMsg((static_cast<std::ostringstream&>(std::ostringstream().flush() << inputs)).str())
因为
flush
是临时的,所以需要std::ostringstream()
。因此,您不能在其上调用带有左值引用的函数(即:std::ostream&
)。像大多数operator<<
变体一样的功能。 flush
调用所做的全部是返回this
指针作为左值引用。