为什么写入临时流失败?

时间:2011-03-03 10:33:02

标签: c++ iostream temporary

请考虑以下代码:

#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;
}

当我执行此操作时,它会给我:

004177FC
Test1

我不明白为什么第二个例子给我带来胡言乱语。临时应该存在直到整个表达式被评估,那么为什么它与第一个例子的行为不一样呢?

1 个答案:

答案 0 :(得分:7)

我测试了它。

我可以猜测operator<<不能将临时绑定到非const引用,因此任何外部定义的运算符&lt;&lt;函数不适用于Foo临时函数,但如果ostreamostringstream有任何内部operator<<成员,那么任何类成员函数都将起作用。

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

非临时性可以绑定到非const引用以获得更专业的重载。

如果您真的需要这个,可以使用包装器

进行解决
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;
  }
};

经过测试和工作。第一个运算符&lt;&lt;将返回基础流。

我也尝试了这个但是它已经重新投入了:

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;

}