ostream链接,输出顺序 [英] ostream chaining, output order

查看:119
本文介绍了ostream链接,输出顺序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个函数以一个 ostream 引用作为参数,写一些数据到流,然后返回一个引用到同一个流,如下: / p>

  #include< iostream> 

std :: ostream& print(std :: ostream& os){
os<< 你好吗? << std :: endl;
return os;
}

int main(){
std :: cout< 你好,世界! << print(std :: cout)<< std :: endl;
}

此代码的输出为:

 你好吗?但是,如果我将链接表达式分成两个语句,那么你可以将链接表达式分成两个语句:


  int main(){
std :: cout< 你好,世界!;
std :: cout<< print(std :: cout)<< std :: endl;
}

那么我至少在输出中获得正确的顺序,十六进制值:

 你好,世界!你好吗? 
0x600ec8

我想了解这里发生了什么。一个正常的函数优先于运算符<< ,这就是为什么输出顺序逆转?编写一个将数据插入 ostream 但也可以链接运算符<

解决方案

您的代码的行为根据C ++标准未指定。



说明



以下(我移除了 std :: endl 为简单起见)

  std :: cout< 你好,世界! << print(std :: cout); 

等效于:

  std :: operator(operator<<<(std :: cout,Hello,World!),print(std :: cout) 

这是一个函数调用,传递两个参数:


$ b b

  • 第一个参数是:运算符<<<(std :: cout,Hello,World!)

  • 第二个参数是: print(std :: cout)



现在,标准没有指定评估参数的顺序。它是未指定的。但你的编译器似乎先评估第二个参数,这就是为什么它打印你好吗?首先,评估第二个参数类型 std :: ostream& ; 然后被传递到上面显示的调用(该值是对象 std :: cout 本身)。

$ b $为什么是十六进制输出?

您得到十六进制输出,因为第二个参数计算为 std :: cout std :: cout 隐式转换为 void *

 

void const * pointer = std :: cout; //隐式转换为指针类型!
std :: cout<< std :: cout< std :: endl;
std :: cout<<指针<< std :: endl;

它将打印相同的值。例如,此示例在 ideone 上打印:

  0x804a044 
0x804a044

t使用显式 cast;而 std :: cout 隐式转换为指针类型。



希望有帮助。







写入将数据插入到流中的函数的正确方式是什么,但是也可以使用operator&

当它取决于你的意思是什么?显然,以下将不工作(如上所述):

  std :: cout< X<< print(std :: cout)<< Y < Z; //未指定的行为!不管你如何写 print() 



但是这是明确定义的:

  print :: cout)<< X<< Y < Z; //明确定义的行为! 


I have a function that takes an ostream reference as an argument, writes some data to the stream, and then returns a reference to that same stream, like so:

#include <iostream>

std::ostream& print( std::ostream& os ) {
  os << " How are you?" << std::endl;
  return os;
}

int main() {
  std::cout << "Hello, world!" << print( std::cout ) << std::endl;
}

The output of this code is:

 How are you?
Hello, world!0x601288

However, if I separate the chaining expressions into two statements, like this

int main() {
  std::cout << "Hello, world!";
  std::cout << print( std::cout ) << std::endl;
}

then I at least get the proper order in the output, but still get a hex value:

Hello, world! How are you?
0x600ec8

I would like to understand what's going on here. Does a normal function take precedence over operator<<, and that's why the output order reverses? What is the proper way to write a function that inserts data into an ostream but that can also chain with operator<<?

解决方案

The behavior of your code is unspecified as per the C++ Standard.

Explanation

The following (I removed std::endl for simplicity)

std::cout << "Hello, world!" << print( std::cout ); 

is equivalent to this:

std::operator(operator<<(std::cout, "Hello, World!"), print(std::cout));

which is a function call, passing two arguments:

  • First argument is : operator<<(std::cout, "Hello, World!")
  • Second argument is : print(std::cout)

Now, the Standard doesn't specify the order in which arguments are evaluated. It is unspecified. But your compiler seems to evaluate the second argument first, that is why it prints "How are you?" first, evaluating the second argument to a value of type std::ostream& which then gets passed to the call shown above (that value is the object std::cout itself).

Why hexadecimal output?

You get hexadecimal output because the second argument evaluates to std::cout, which is being printed as hexadecimal number, because std::cout implicitly converts into pointer value of void* type, which is why it is printed as hexadecimal number.

Try this:

void const *pointer = std::cout; //implicitly converts into pointer type!
std::cout << std::cout << std::endl;
std::cout << pointer << std::endl;

It will print the same value for both. For example, this example at ideone prints this:

0x804a044
0x804a044 

Also note that I didn't use explicit cast; rather std::cout is implicitly converted into pointer type.

Hope that helps.


What is the proper way to write a function that inserts data into an ostream but that can also chain with operator<

When it depends on what you mean by chaining? Obviously, the following wouldn't work (as explained above):

std::cout << X << print(std::cout) << Y << Z; //unspecified behaviour!

No matter how you write print().

However this is well-defined:

print(std::cout) << X << Y << Z; //well-defined behaviour!

这篇关于ostream链接,输出顺序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆