我希望能够做到:

foo(stringstream()<<"number = " << 500);

编辑:单行解决方案至关重要,因为这是出于日志记录的目的。这些将围绕代码。

在foo内部,会将字符串输出到屏幕或类似的东西。

现在,由于stringstream的operator <
foo(ostream& o);

但是如何将ostream&转换为字符串? (或char *)。
也欢迎实现此用例的不同方法。

最佳答案

显而易见的解决方案是在dynamic_cast中使用foo。但是给定的
代码仍然无法正常工作。 (您的示例将编译,但不会执行任何操作
您认为应该。)表达式std::ostringstream()是一个
临时,您不能使用临时来初始化非常量引用,
std::operator<<( std::ostream&, char const*)的第一个参数
是非常量引用。 (您可以在
暂时的。像std::ostream::operator<<( void const* )一样。所以代码
会编译,但不会如您所愿。

您可以使用以下方法解决此问题:

foo( std::ostringstream().flush() << "number = " << 500 );
std::ostream::flush()返回非常量引用,因此没有
进一步的问题。在新创建的视频流上,它是无人值守的。
不过,我想您会同意这不是最优雅或最直观的方法
解决方案。

在这种情况下,我通常要做的是创建一个包装器类,
包含它自己的std::ostringstream,并提供模板
成员operator<<转发到包含std::ostringstream。您的函数foo将采用const对此的引用,或者我经常做的是使用析构函数调用
直接使用foo,因此客户端代码甚至不必担心
它;它的功能类似于:
log() << "number = " << 500;

函数log()返回包装类的实例(但请参见
下面),并且此类的(最终)析构函数调用您的函数foo

这有一个小问题。返回值可以复制,
并在复制后立即销毁。哪个会破坏
我刚才解释的实际上,因为std::ostringstream不是
可复制的,甚至无法编译。解决方案是将所有
实际逻辑,包括std::ostringstream实例和
在单独的实现类中调用foo的析构函数逻辑具有
公共(public)包装器有一个boost::shared_ptr并转发。或者
只需在类中重新实现一些共享指针逻辑即可:
class LogWrapper
{
    std::ostringstream* collector;
    int* useCount;
public:
    LogWrapper()
        : collector(new std::ostringstream)
        , useCount(new int(1))
    {
    }

    ~LogWrapper()
    {
        -- *useCount;
        if ( *useCount == 0 ) {
            foo( collector->str() );
            delete collector;
            delete useCount;
        }
    }

    template<typename T>
    LogWrapper& operator<<( T const& value )
    {
        (*collector) << value;
        return *this;
    }
};

注意,很容易扩展它以支持可选的日志记录。只是
提供LogWrapper的构造函数,该构造函数将collector设置为NULL,并在operator<<中对此进行测试。

编辑:

我发生另一件事:您可能要检查是否
由于异常而调用析构函数,而不是调用
在这种情况下为foo。从逻辑上讲,我希望您唯一的异常(exception)
可能得到的是std::bad_alloc,但是总会有一个用户
像这样写:
log() << a + b;

其中+是用户定义的引发的重载。

10-08 00:31