7

考虑以下代码:

#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

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

4

1 回答 1

8

我测试了它。

我猜想operator<<不能将临时对象绑定到非 const 引用,因此任何外部定义的 operator<< 函数都不能在 Foo 临时对象上工作,但任何类成员函数都可以,如果ostreamostringstream有任何内部operator<<成员它们将起作用。

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

non-temporary 可以绑定到 non-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;
  }
};

测试和工作。第一个 operator<< 将返回底层流。

我也试过这个,但它核心转储:

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;

}
于 2011-03-03T11:46:48.233 回答