【问题标题】:sending c-string to non-lvalue std::ostringstream weird behaviour将 c-string 发送到非左值 std::ostringstream 奇怪的行为
【发布时间】:2019-05-20 17:28:27
【问题描述】:

测试代码:

#include <iostream>
#include <sstream>

int main() {
  std::ostringstream q;

  std::cout << (dynamic_cast<std::ostringstream&>(q<<"hello"<<101).str()) << "\n";
  std::cout << (dynamic_cast<std::ostringstream&>(std::ostringstream()<<"hello"<<101).str()) << "\n";
  return 0;
}

编译:g++ test.cpp 输出:

hello101
hello101

编译:g++ -std=c++98 test.cpp 输出:

hello101
0x4b2ec0101

看起来第二个字符串包含指向“hello”字符串的指针,而不是字符串本身。为什么? 是c++98标准的一些“特性”还是gcc中的bug?

【问题讨论】:

  • 在表达式中创建的临时对象不会被销毁,直到整个表达式完成时(即到达;)超出范围。

标签: c++


【解决方案1】:

在C++03中,负责打印出C字符串的非成员operator&lt;&lt;(source),即

template< class Traits >
basic_ostream<char,Traits>& operator<<( basic_ostream<char,Traits>& os,  
                                        const char* s );

无法接受右值流,因此选择了成员重载(继承自 std::ostream 基类)(source):

basic_ostream& operator<<( const void* value );

这会打印出地址。

在C++11中,有一个右值流插入操作符,

template< class CharT, class Traits, class T >
basic_ostream< CharT, Traits >& operator<<( basic_ostream<CharT,Traits>&& os, 
                                            const T& value );

确保左值和右值流的行为相同。请注意,此重载不能用 C++03 编写,因为绑定到右值的唯一方法是通过 const 左值引用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-08-12
    • 2013-10-28
    • 1970-01-01
    • 2013-11-19
    • 2016-03-02
    • 1970-01-01
    • 1970-01-01
    • 2012-07-07
    相关资源
    最近更新 更多