为什么写入临时流失败?

问题描述:

请考虑以下代码:

#include <sstream>
#include <iostream>

class Foo : public std::stringstream {
public:
    ~Foo() { std::cout << str(); }
};

int main()
{
    Foo foo;
    foo << "Test1" << std::endl;

    Foo() << "Test2" << std::endl;

    return 0;
}

执行此操作时,它会显示:

When I execute this, it gives me:

004177FC
Test1

我不明白为什么第二个例子给了我胡言乱语。

I do not understand why the second example gives me gibberish. The temporary should live until the entire expression is evaluated, so why does it not behave the same as the first example?

I测试它。

我可以猜测,运算符<< 不能绑定一个临时的非const引用,所以任何外部定义的运算符<函数不会对Foo临时工作,但是任何类成员都将如果 ostream ostringstream code>

I can guess that operator<< cannot bind a temporary to a non-const reference, so any externally defined operator<< functions will not work on the Foo temporary, but any class member ones will so if ostream or ostringstream has any internal operator<< members they will work.

因此,可能是指针的重载是一个成员函数而特殊的const char *是从外部声明的。

Therefore it may be that the overload to a pointer is a member function whilst the special one for const char * is externally declared.

非临时的可以绑定到非const引用为更多的专家超载。

The non-temporary can bind to the non-const reference for the more specialist overload.

如果你真的需要这个,你可以用一个包装器解决

If you really need this you can workaround with a wrapper

class Foo :
{
    mutable std::ostringstream oss;
public:
  ~Foo()
  {
    std::cout << oss.str();
  }

  template<typename T>
  std::ostream&
  operator<<( const T& t ) const
  {
      return oss << t;
  }
};

测试并正常工作。第一运算符<<

Tested and works. The first operator<< will return you the underlying stream.

我也尝试过了,但它coredumped:

I tried this too but it coredumped:

class Foo : std::ostringstream
{
    Foo & nonconstref;
public:
   Foo() : nonconstref( *this ) {}
  ~Foo()
  {
    std::cout << str();
  }

  template<typename T>
  std::ostream&
  operator<<( const T& t ) const
  {
      return nonconstref << t;
  }
};

这也有效:

class Foo : public std::ostringstream
{
public:
   Foo()  {}
  ~Foo()
  {
    std::cout << str();
  }

  Foo& ncref()
  {
       return *this;
  }
};

int main()
{
    Foo foo;
    foo << "Test1" << std::endl;

    Foo().ncref() << "Test2" << std::endl;

}