A function that prints something in std :: ostream and returns std :: ostream?

I want to write a function that outputs something to the ostream that is being passed and returns a stream, for example:

 std::ostream& MyPrint(int val, std::ostream* out) { *out << val; return *out; } int main(int argc, char** argv){ std::cout << "Value: " << MyPrint(12, &std::cout) << std::endl; return 0; } 

It would be convenient to print a value like this and insert a function call into the chain of output statements, as it was in main() .

However, it does not work and prints this:

 $ ./a.out 12Value: 0x6013a8 

The desired result will be as follows:

 Value: 12 

How can i fix this? Should operator<< be defined instead?

UPDATE: Clarified what the desired result will be.

UPDATE2:. Some people did not understand why I would print such a number using the function instead of direct printing. This is a simplified example, and the function actually prints a complex object, not an int .

+6
c ++ outputstream ostream
source share
7 answers

You cannot fix this function. Nothing in the specification requires a compiler to evaluate a function call in an expression in any particular order relative to some unrelated statement in the same expression. Thus, without changing the call code, you cannot evaluate MyPrint() after std::cout << "Value: "

The order from left to right is set for expressions consisting of several consecutive <operators, so this will work. Operator point <Flow return is that when the operators are bound, each of them is provided with an LHS by evaluating the operator to its left.

You cannot achieve the same with free function calls, because they do not have LHS. MyPrint() returns an object equal to std::cout , as well as std::cout << "Value: " , so you effectively do std::cout << std::cout , which prints this hex value.

Since the desired result:

 Value: 12 

the β€œright” thing is to really override the operator <This often means you need to either make it a friend or do it:

 class WhateverItIsYouReallyWantToPrint { public: void print(ostream &out) const { // do whatever } }; ostream &operator<<(ostream &out, const WhateverItIsYouReallyWantToPrint &obj) { obj.print(out); } 

If overriding operator<< for your class is not suitable, for example, because there are several formats that you want to print, and you want to write different functions for each of them, then you should either abandon the idea of ​​a chain of operators and just call the function, or write several classes that take your object as a constructor parameter, each with different operator overloads.

+11
source share

You want to make MyPrint a class with the operator friend <: lt ;:

 class MyPrint { public: MyPrint(int val) : val_(val) {} friend std::ostream& operator<<(std::ostream& os, const MyPrint& mp) { os << mp.val_; return os; } private: int val_; }; int main(int argc, char** argv) { std::cout << "Value: " << MyPrint(12) << std::endl; return 0; } 

This method requires that you inject the MyPrint object into the stream of your choice. If you really need the ability to change which thread is active, you can do this:

 class MyPrint { public: MyPrint(int val, std::ostream& os) : val_(val), os_(os) {} friend std::ostream& operator<<(std::ostream& dummy, const MyPrint& mp) { mp.os_ << mp.val_; return os_; } private: int val_; std::ostream& os_ }; int main(int argc, char** argv) { std::cout << "Value: " << MyPrint(12, std::cout) << std::endl; return 0; } 
+5
source share

You have two options. First, using what you already have:

 std::cout << "Value: "; MyPrint(12, &std::cout); std::cout << std::endl; 

Another, more similar to C ++, should replace MyPrint() with the corresponding std::ostream& operator<< . There is already one for int , so I will make one a little more complicated:

 #include <iostream> struct X { int y; }; // I'm not bothering passing X as a reference, because it a // small object std::ostream& operator<<(std::ostream& os, const X x) { return os << xy; } int main() { X x; xy = 5; std::cout << x << std::endl; } 
+3
source share

It is not possible to do what you expect from this, because functions are evaluated.

Is there any specific reason you need to write directly to Ostream? If not, just MyPrint will return the string. If you want to use the stream inside MyPrint to generate output, just use strstream and return the result.

+1
source share

Firstly, there is no reason not to transfer to ostream by reference, and not by pointer:

 std::ostream& MyPrint(int val, std::ostream& out) { out << val; return out; } 

If you really don't want to use std::ostream& operator<<(std::ostream& os, TYPE) , you can do this:

 int main(int argc, char** argv){ std::cout << "Value: "; MyPrint(12, std::cout) << std::endl; return 0; } 
0
source share

After changing the pointer to the link, you can do this:

 #include <iostream> std::ostream& MyPrint(int val, std::ostream& out) { out << val; return out; } int main(int, char**) { MyPrint(11, std::cout << "Value: ") << std::endl; return 0; } 

The MyPrint syntax is essentially an operator<< spread, but with an additional argument.

0
source share

In your case, the answer is explicit:

  std::cout << "Value: " << 12 << std::endl; 

If this is not enough, explain what result you want to see.

-one
source share

All Articles