I don't understand what this ostream function declaration means:
ostream& operator<< (ostream& (*pf)(ostream&));
(specifically, the (*pf)(ostream&) part). I want to do something like:
void print(ostream& os){
cout << os;
}
but I get the error:
Invalid operands to binary expression ('ostream' . . . and 'ostream')
I don't understand what this ostream function declaration means:
ostream& operator<< (ostream& (*pf)(ostream&));
Have you seen functions like std::endl, std::flush, std::hex, std::dec, std::setw...? They can all be "sent" to a stream using "<<", then they get called with the stream as a function argument and do their magic on the stream. They actually match the ostream& (*pf)(ostream&) argument above, and that operator's the one that lets them be used. If we look at the Visual C++ implementation...
_Myt& operator<<(_Myt& (__cdecl *_Pfn)(_Myt&))
{
return ((*_Pfn)(*this));
}
...you can see if just calls the function, passing the stream it's used on as an argument. The functions are expected to return a reference to the same stream argument, so that further << operations may be chained, or the stream may be implicitly converted to bool as a test of stream state.
See http://en.cppreference.com/w/cpp/io/manip for more information about io manipulators.
You wanted help with:
void print(ostream& os){
cout << os;
}
The issue here is that you're sending the ostream argument to another stream - cout - and it doesn't know what you want it to do with it.
To send the current content of os to cout, try:
void print(ostream& os){
cout << os.rdbuf();
}
Or if you want to print some actual data to the stream represented by the argument:
void print(ostream& os){
os << "show this!\n";
}
print(std::cout); // to write "show this!\n" to `std::cout`
print(std::cerr); // to write "show this!\n" to `std::cerr`
What the declaration means.
The formal argument …
ostream& (*pf)(ostream&)
declares an argument named pf which is a pointer, to which you can apply an argument parenthesis with an ostream& argument, which constitutes a call that returns an ostream& as its result.
It can be simplified to just …
ostream& pf(ostream&)
where you can more easily see that it's a function.
The drawback is that this form is seldom used, so not everybody is aware that it decays to the first form (much the same as e.g. int x[43] as a formal argument type is effectively the same as just int x[] because both these forms decay to just int* x in the function type, so that in the function body you can even increment that x).
What it’s used for.
A function of the above form is usually an output stream manipulator. That means, you can pass it to the << output operator. What happens then is just that << calls that function, with the stream as argument, as specified by C++11 §27.7.3.6.3/1 and 2:
basic_ostream<charT,traits>& operator<<
(basic_ostream<charT,traits>& (*pf)(basic_ostream<charT,traits>&))
Effects: None. Does not behave as a formatted output function (as described in 27.7.3.6.1).
Returns: pf(*this).
There is also an overload of << that takes a similar function, but with std::basic_ios& argument and result, and one that takes a function with std::ios_base argument and result.
Class std::ios_base is the base of the iostreams class hierarchy and the standard manipulators defined at that level are …:
Format flag manipulators:
boolalpha, noboolalpha, showbase, noshowbase, showpoint, noshowpoint, showpos, noshowpos, skipws, noskipws, uppercase, nouppercase, unitbut and nounitbuf.
Adjustment field manipulators:
internal, left and right.
Numeral system base manipulators:
dec, hex and oct.
Floating point number presentation manipulators:
fixed, scientific, hexfloat and defaultfloat.
Manipulators that take user arguments don’t follow this form and those that the standard provides are in a separate header called <iomanip>.
Example: a user-defined manipulator.
Code:
#include <iostream>
#include <string>
// With Visual C++, if necessary define __func__ as __FUNCTION__.
using namespace std;
class Logger
{
private:
string funcname_;
static int call_level;
auto
static indent( ostream& stream )
-> ostream&
{ return (stream << string( 4*call_level, ' ' )); }
public:
Logger( string const& funcname )
: funcname_( funcname )
{
clog << indent << "-> " << funcname_ << endl;
++call_level;
}
~Logger()
{
--call_level;
clog << indent << "<- " << funcname_ << endl;
}
};
int Logger::call_level = 0;
#define WITH_LOGGING Logger logging( __func__ )
void c() { WITH_LOGGING; }
void b() { WITH_LOGGING; c(); }
void a() { WITH_LOGGING; b(); }
auto main() -> int { a(); }
Output, which shows the calls and returns, nicely indented:
-> a
-> b
-> c
<- c
<- b
<- a
The parameter portion of the declaration:
ostream& operator<< (ostream& (*pf)(ostream&));
is a function pointer syntax.
The expression:
ostream& (*pf)(ostream&)
Declares a pointer to a function, pf, that takes an ostream& parameter and returns a reference to an ostream.
If I declare a function:
ostream& my_function(ostream& output);
Then I can pass a pointer to the function as the parameter:
operator<< (my_function);
Read up on function pointer syntax. Search the web and stackoverflow.
Related
I was working on a function which looks like so:
inline std::ostream& mvUp(int n,std::ostream& ss){
char u[8];
sprintf(u,"\033[%dA",n);
ss<<u;
return ss;
}
and using it like so:
std::cout<<mvUp(1);
however it shows error:
std::cout<<mvUp(1);
| ^_____too few args in function call
^_______________no operator "<<" match these operands
I also tried: std::cout<<mvUp(1,std::cout); but still not working.
std::cout<<mvUp(1);
^_______________no operator "<<" match these operands
now when I try making it template,
template <int n>
inline std::ostream& mvUp(std::ostream& ss){
char u[8];
sprintf(u,"\033[%dA",n);
ss<<u;
return ss;
}
and use it: std::cout<<mvUp<1>, this works totally fine but the problem with this is that templates take const args.
Not able to figure out where am I getting wrong. Also how is it working in templates when I am not passing any args?
Modern C++ code uses std::string, and other classes. This makes implementing this kind of an overload trivial.
#include <string>
#include <sstream>
inline std::string mvUp(int n) {
std::ostringstream o;
o << "\033[" << n << "A";
return o.str();
}
Then, everything will work automatically:
std::cout<<mvUp(1);
Your mvUp returns std::string, and the existing << overload takes care of the rest.
The fact that std::ostream& mvUp(std::ostream& ss); std::cout << mvUp<1> works is not a peculiarity of C++ function call syntax.
std::cout has its operator<< overloaded to accept single-parameter functions like this one, and call them by passing itself as the first argument.
Given std::ostream& mvUp(int n,std::ostream& ss);, std::cout<<mvUp(1) doesn't work because your function doesn't have one parameter. And std::cout << mvUp(1,std::cout); doesn't work because your function returns std::ostream&, which can't be printed.
The generic solution is to make a class with overloaded operator<<. But, as the other answer suggests, here you can just make a function that returns std::string, and print its return value.
You are trying to create a custom ostream manipulator, similar to std::setw() and other manipulators from the <iomanip> library. But what you have written is not the correct way to implement that. Your manipulator needs to return a type that holds the information you want to manipulate the stream with, and then you need to overload operator<< to stream out that type. That will give you access to the ostream which you can then manipulate as needed.
Try something more like this:
struct mvUpS
{
int n;
};
mvUpS mvUp(int n) {
return mvUpS{n};
}
std::ostream& operator<<(std::ostream& ss, const mvUpS &s) {
return ss << "\033[" << s.n << "A";
}
Now std::cout << mvUp(1); will work as expected.
Demo
I have create a program to overload << operator for my class.
I have a doubt about the return type of the overloaded method.
When i am returning the out from the overloaded operator function the program is working fine.
But when i am not returning any thing from the function the program crashing under one condition.
In many C++ resource i have read that the return type is necessary to print operators in cascading .
Condition 1 : Passing
When i am using statement
// cout<<"\n"<<mv1<<mv2<<mv3;
Every thing is working fine. Passing without return from overloaded function.
Condition 2:Failing
When i am using statemtent
cout<<"\n"<
This i know that return was not there so the program crashed at runtime.
But the question is what made program run in Condition 1 . Even without the return statement was not present in the overloading function.
Program below
I have create a program to overload << operator for my class.
I have a doubt about the return type of the overloaded method.
When i am returning the out from the overloaded operator function the program is working fine.
But when i am not returning any thing from the function the program crashing under one condition.
In many C++ resource i have read that the return type is necessary to print operators in cascading .
Condition 1 : Passing
When i am using statement
// cout<<"\n"<<mv1<<mv2<<mv3;
Every thing is working fine. Passing without return from overloaded function.
Condition 2:Failing
When i am using statemtent
cout<<"\n"<
This i know that return was not there so the program crashed at runtime.
But the question is what made program run in Condition 1 . Even without the return statement was not present in the overloading function.
Program below
#include <iostream>
#include <stdio.h>
using namespace std;
class myvar{
private:
int var_x,var_y;
public:
friend ostream& operator<<(ostream &out,myvar n);
void setvalue(int x,int y)
{
var_x = x ;
var_y = y ;
}
};
ostream& operator<<(ostream &out,myvar n)
{
cout<<"("<<n.var_x<<","<<n.var_y<<")";
//return out;
}
int main()
{
myvar mv1,mv2,mv3;
mv1.setvalue(10,20);
mv2.setvalue(30,40);
mv3.setvalue(50,60);
//Working
// cout<<"\n"<<mv1<<mv2<<mv3;
//Not Working
// cout<<"\n"<<mv1<<mv2<<mv3<<"Hello"<<1243<<11.5;
}
This code has Undefined Behavior.
This is very bad. Usually it means that a crash will happen (but technically anything can happen).
ostream& operator<<(ostream &out,myvar n)
{
out<<"("<<n.var_x<<","<<n.var_y<<")"; // fixed cout to out.
//return out;
}
This is because you specify a return type in the function signature.
ostream& operator<<(ostream &out,myvar n)
^^^^^^^^
If your function does not contain a return keyword then your code is invalid. So for the function as defined (with the commented out return) your program will most likely crash.
If you change your code to:
void operator<<(ostream &out,myvar n)
{
out<<"("<<n.var_x<<","<<n.var_y<<")";
}
Now it will compile (be valid) and work.
But the consequence is you can not chain stream operations together.
myvar x;
// Set some value in x
// This will work fine.
std::cout << x;
// But this will fail to compile.
std::cout << x << " Another Thing";
Because the first call to operator<< returns a void the second call to operator<< does not know what to do.
So your best bet is to return the stream to allow chaining.
ostream& operator<<(ostream &out,myvar n)
{
out<<"("<<n.var_x<<","<<n.var_y<<")";
return out;
}
PS: Some space characters would be really nice to aid readability.
// This is easier to read for a human.
std::ostream& operator<<(std::ostream &out, myvar n)
{
out << "(" << n.var_x << "," << n.var_y << ")";
return out;
}
Yes, you always return the passed in ostream and probably want to pass in a const reference to the value you want outputed:
ostream& operator<<(ostream &out, const myvar& n)
{
out << "(" << n.var_x << "," << n.var_y << ")";
return out;
}
My biggest doubt is that why chaining of << in following statement
is working even without the return of out from overloaded function.
cout<<"\n"<<mv1<<mv2<<mv3;
I have the following code:
#include <iostream>
using namespace std;
ostream& f(ostream& os) {
return os << "hi";
}
int main() {
cout << "hello " << f << endl;
return 0;
}
And somehow this works - the output is "hello hi". How does this get interpreted by the compiler? I don't understand how a function can be inserted into a stream.
std::ostream has an operator<< overload that receives a pointer to a function with the signature such as the one you wrote (number 11 in this list):
basic_ostream& operator<<(
std::basic_ostream<CharT,Traits>& (*func)(std::basic_ostream<CharT,Traits>&) );
which just calls the given function passing itself as argument. This overload (along with several similar others) is there to allow you to implement stream manipulators, i.e. stuff that you output in the stream with an << and changes the state of the stream from there. For example, our version of the (incorrectly) ubiquitous std::endl may be implemented as
std::ostream &myendl(std::ostream &s) {
s<<'\n';
s.flush();
return s;
}
which can then be used exactly as the "regular" std::endl:
std::cout<<"Hello, World!"<<myendl;
(the actual implementation is templated and a bit more complicated because it has to work even with wide streams, but you got the idea)
std::ostream::operator<< has an overload which accepts a function as parameter; and the body of that overload is to invoke the function given.
This is exactly how endl works in fact. endl is actually a function similar to:
ostream &endl(ostream &os)
{
os << '\n';
os.flush();
return os;
}
How do I write user-defined stream manipulators in C++ that control the format of streaming a self-written class?
Specifically, how would I write simple manipulators verbose and terse to control the amount of output streamed?
My environment is GCC, versions 4.5.1 and up.
Example:
class A
{
...
};
A a;
// definition of manipulators verbose and terse
cout << verbose << a << endl; // outputs a verbosely
cout << terse << a << endl; // outputs a tersely
PS: What follows is just a side question, feel free to ignore it: Can this portably be extended to manipulators taking arguments? Josuttis writes in "The C++ Standard Library" near the end of section 13.6.1 that writing manipulators taking argument is implementation dependent. Is this still true?
I don't see any reason for them to be implementation dependent.
This is comething that I use, for the actual manipulator, create a function that returns an instance of the following helper. If you need to store the data, just store it inside the helper, some global variable, singleton, etc...
/// One argument manipulators helper
template < typename ParType >
class OneArgManip
{
ParType par;
std::ostream& (*impl)(std::ostream&, const ParType&);
public:
OneArgManip(std::ostream& (*code)(std::ostream&, const ParType&), ParType p)
: par(p), impl(code) {}
// calls the implementation
void operator()(std::ostream& stream) const
{ impl(stream,par); }
// a wrapper that allows us to use the manipulator directly
friend std::ostream& operator << (std::ostream& stream,
const OneArgManip<ParType>& manip)
{ manip(stream); return stream; }
};
Example of a manipulator based on this:
OneArgManip<unsigned> cursorMoveUp(unsigned c)
{ return OneArgManip<unsigned>(cursorMoveUpI,c); }
std::ostream& cursorMoveUpI(std::ostream& stream, const unsigned& c)
{ stream << "\033[" << c << "A"; return stream; }
For some explanation:
u use the manipulator, that returns a new instance of the helper bound to an implementation of the helper
stream tries to process the helper, that invokes the << overload on the helper
that invokes the () operator on the helper
that invokes the real implementation of the helper with the parameter passed from the original manipulator call
If you want I can post 2 param and 3 param helpers as well. The principle is the same though.
I'm trying to write my own logging class and use it as a stream:
logger L;
L << "whatever" << std::endl;
This is the code I started with:
#include <iostream>
using namespace std;
class logger{
public:
template <typename T>
friend logger& operator <<(logger& log, const T& value);
};
template <typename T>
logger& operator <<(logger& log, T const & value) {
// Here I'd output the values to a file and stdout, etc.
cout << value;
return log;
}
int main(int argc, char *argv[])
{
logger L;
L << "hello" << '\n' ; // This works
L << "bye" << "alo" << endl; // This doesn't work
return 0;
}
But I was getting an error when trying to compile, saying that there was no definition for operator<< (when using std::endl):
pruebaLog.cpp:31: error: no match for ‘operator<<’ in ‘operator<< [with T = char [4]](((logger&)((logger*)operator<< [with T = char [4]](((logger&)(& L)), ((const char (&)[4])"bye")))), ((const char (&)[4])"alo")) << std::endl’
So, I've been trying to overload operator<< to accept this kind of streams, but it's driving me mad. I don't know how to do it. I've been loking at, for instance, the definition of std::endl at the ostream header file and written a function with this header:
logger& operator <<(logger& log, const basic_ostream<char,char_traits<char> >& (*s)(basic_ostream<char,char_traits<char> >&))
But no luck. I've tried the same using templates instead of directly using char, and also tried simply using "const ostream& os", and nothing.
Another thing that bugs me is that, in the error output, the first argument for operator<< changes, sometimes it's a reference to a pointer, sometimes looks like a double reference...
endl is a strange beast. It isn't a constant value. It's actually, of all things, a function. You need a special override to handle the application of endl:
logger& operator<< (logger& log, ostream& (*pf) (ostream&))
{
cout << pf;
return log;
}
This accepts insertion of a function that takes an ostream reference and returns an ostream reference. That's what endl is.
Edit: In response to FranticPedantic's interesting question of "why can't the compiler deduce this automatically?". The reason is that if you delve yet deeper, endl is actually itself a template function. It's defined as:
template <class charT, class traits>
basic_ostream<charT,traits>& endl ( basic_ostream<charT,traits>& os );
That is, it can take any sort of ostream as its input and output. So the problem isn't that the compiler can't deduce that T const & could be a function pointer, but that it can't figure out which endl you meant to pass in. The templated version of operator<< presented in the question would accept a pointer to any function as its second argument, but at the same time, the endl template represents an infinite set of potential functions, so the compiler can't do anything meaningful there.
Providing the special overload of the operator<< whose second argument matches a specific instantiation of the endl template allows the call to resolve.
endl is an IO manipulator, which is a functor that accepts a stream by reference, performs some operation on it, and returns that stream, also by reference. cout << endl is equivalent to cout << '\n' << flush, where flush is a manipulator that flushes the output buffer.
In your class, you just need to write an overload for this operator:
logger& operator<<(logger&(*function)(logger&)) {
return function(*this);
}
Where logger&(*)(logger&) is the type of a function accepting and returning a logger by reference. To write your own manipulators, just write a function that matches that signature, and have it perform some operation on the stream:
logger& newline(logger& L) {
return L << '\n';
}
I believe that the problem is your stream doesn't overload operator<< to accept a function that has the same type as std::endl as illustrated in this answer: std::endl is of unknown type when overloading operator<<
In C++ it is the stream buffer that encapsulates the underlying I/O mechanisim. The stream itself only encapsulates the conversions to string, and the I/O direction.
Thus you should be using one of the predefined stream classes, rather than making your own. If you have a new target you want your I/O to go to (like a system log), what you should be creating is your own stream buffer (derived from std::streambuf).