std::ostringstream 打印 c 字符串的地址而不是其内容

2024-08-14C/C++开发问题
1

本文介绍了std::ostringstream 打印 c 字符串的地址而不是其内容的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

问题描述

我偶然发现了一个我一开始无法解释的奇怪行为(参见 ideone):

I have stumbled on a weird behavior that I just could not explain at first (see ideone):

#include <iostream>
#include <sstream>
#include <string>

int main() {
  std::cout << "Reference     : "
            << (void const*)"some data"
            << "
";

  std::ostringstream s;
  s << "some data";
  std::cout << "Regular Syntax: " << s.str() << "
";

  std::ostringstream s2;
  std::cout << "Semi inline   : "
            << static_cast<std::ostringstream&>(s2 << "some data").str()
            << "
";

  std::cout << "Inline        : "
            << dynamic_cast<std::ostringstream&>(
                 std::ostringstream() << "some data"
               ).str()
            << "
";
}

给出输出:

Reference     : 0x804a03d
Regular Syntax: some data
Semi inline   : some data
Inline        : 0x804a03d

令人惊讶的是,在最后一次演员表中,我们有地址,而不是内容!

Surprisingly, in the last cast we have the address, and not the content!

为什么会这样?

推荐答案

表达式std::ostringstream() 创建一个临时的,operator<<< 需要const char* as argument 是一个自由函数,但是这个自由函数不能临时调用,因为函数的第一个参数的类型是std::ostream& 不能绑定到临时对象.

The expressionstd::ostringstream() creates a temporary, and operator<< which takes const char* as argument is a free function, but this free function cannot be called on a temporary, as the type of the first parameter of the function is std::ostream& which cannot be bound to temporary object.

话虽如此,<<std::ostringstream() <<一些数据" 解析为对打印地址的 void* 重载的成员函数的调用.请注意,可以在临时上调用成员函数.

Having said that, <<std::ostringstream() << "some data" resolves to a call to a member function which is overloaded for void* which prints the address. Note that a member function can be invoked on the temporary.

为了调用自由函数,您需要将临时(即右值)转换为左值,这是您可以执行的一个技巧:

In order to call the free function, you need to convert temporary (which is rvalue) into a lvalue, and here is one trick that you can do:

 std::cout << "Inline        : "
            << dynamic_cast<std::ostringstream&>(
                 std::ostringstream().flush() << "some data"
               ).str()
            << "
";

std::ostringstream().flush() 返回 std::ostream& 这意味着,现在可以调用自由函数,传递返回的引用作为第一个论点.

That is, std::ostringstream().flush() returns std::ostream& which means, now the free function can called, passing the returned reference as first argument.

另外,你不需要在这里使用 dynamic_cast(这很慢,因为它是在运行时完成的),因为对象的类型是非常已知的,所以你可以使用static_cast(它在编译时完成得很快):

Also, you don't need to use dynamic_cast here (which is slow, as it is done at runtime), for the type of the object is pretty much known, and so you can use static_cast (which is fast as it is done at compile-time):

 std::cout << "Inline        : "
            << static_cast<std::ostringstream&>(
                 std::ostringstream().flush() << "some data"
               ).str()
            << "
";

应该可以正常工作.

这篇关于std::ostringstream 打印 c 字符串的地址而不是其内容的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

The End

相关推荐

无法访问 C++ std::set 中对象的非常量成员函数
Unable to access non-const member functions of objects in C++ std::set(无法访问 C++ std::set 中对象的非常量成员函数)...
2024-08-14 C/C++开发问题
17

从 lambda 构造 std::function 参数
Constructing std::function argument from lambda(从 lambda 构造 std::function 参数)...
2024-08-14 C/C++开发问题
25

STL BigInt 类实现
STL BigInt class implementation(STL BigInt 类实现)...
2024-08-14 C/C++开发问题
3

使用 std::atomic 和 std::condition_variable 同步不可靠
Sync is unreliable using std::atomic and std::condition_variable(使用 std::atomic 和 std::condition_variable 同步不可靠)...
2024-08-14 C/C++开发问题
17

在 STL 中将列表元素移动到末尾
Move list element to the end in STL(在 STL 中将列表元素移动到末尾)...
2024-08-14 C/C++开发问题
9

为什么禁止对存储在 STL 容器中的类重载 operator&amp;()?
Why is overloading operatoramp;() prohibited for classes stored in STL containers?(为什么禁止对存储在 STL 容器中的类重载 operatoramp;()?)...
2024-08-14 C/C++开发问题
6