我想编写一个宏,该宏将std :: ostream&operator 来重写示例本身,但是将输出发送到std :: cout并不是目标,这只是我为示例选择的测试目标。

我正在使用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指针作为左值引用。

08-27 19:57