When we use printf then we use format specifiers (such as %c,%p) but when we use cout we don't use them why and what is being done in background because which we are not using them ?
I know they are used in differently in c and c++ but still i want to know how formatting is being done in cout, while it is done in printf through format specifiers.
In C++ the ostream::operator<< is overloaded for different types. You can try and dig through your standard library implementation to see exactly what it looks like, but it will boil down to something that is approximately equivalent to the following:
class ostream
{
public:
ostream& operator<<( int val );
ostream& operator<<( float val );
ostream& operator<<( const char* val );
};
A real implementation will be much more complicated than the above, but that is roughly the idea. The hope was that this implementation would be more efficient than printf because the compiler could more easily inline code when appropriate. Consider the following:
int val = 0;
printf("%d\n", val);
std::cout << val << std::endl;
In the case of the printf a naively compiled program (one compiled by a compiler with no knowledge of format specifiers) would have to do the parsing of "%d\n" at runtime. Contrast that with the std::cout call, in which case the compiler merely needs to figure out which overload to use, and can then inline the code.
That said, there is nothing in the c standard that says a compiler can't parse the format specifiers at compile time if they are available. In practice the performance difference between a c style logging library using format specifiers and c++ ostreams is... nuanced.
Because printf is properly designed and cout has nasty internal state. With printf, the way you want each argument formatted is explicit in the format string; there is no hidden state. With cout, you can also control formatting (things like field width, etc.), but it's a hidden state inside the iostream object. If the previous user of the stream has left it in a non-default state, you'll do the wrong thing unless you explicitly reset the state. You don't even want to think about what happens in multi-threaded usage cases...
Basically the answer is operator overloading. Functions can have the same name as long as they take different parameters. operator<< is the function name you're wondering about. The compiler knows the type of what you're trying to print out, and calls the correct operator<<.
This is why if you create your own object you can't just write std::cout << yourObject; and expect it to work how you'd probably like it to. You have to specify how it should be printed,
ostream& operator<<(ostream& os, const YourObject& rhs) {
os << rhs.member;
return os;
}
But, happily, that's already been done for you behind the scenes in the case of something like an int. See: http://en.cppreference.com/w/cpp/io/basic_ostream/operator_ltlt2 for a full list of provided overloads.
Related
I have a class SpecialString. It has an operator overload / conversion function it uses any time it's passed off as a const char*. It then returns a normal c-string.
class SpecialString
{
...
operator char* () const { return mCStr; }
...
};
This used to work a long time ago (literally 19 years ago) when I passed these directly into printf(). The compiler was smart enough to know that argument was meant to be a char* and it used the conversion function, but the now g++ complains.
SpecialString str1("Hello"), str2("World");
printf("%s %s\n", str1, str2);
error: cannot pass object of non-POD type 'SPECIALSTRING' (aka 'SpecialString') through variadic method; call will abort at runtime [-Wnon-pod-varargs]
Is there any way to get this to work again without changing the code? I can add a deref operator overload function that returns the c-string and pass the SpecialString objects around like this.
class SpecialString
{
...
operator CHAR* () const { return mCStr; }
char* operator * () const { return mCStr; }
...
};
SpecialString str1("Hello"), str2("World");
printf("%s %s\n", *str1, *str2);
But I'd prefer not to because this requires manually changing thousands of lines of code.
You could disable the warning, if you don't want to be informed about it... but that's a bad idea.
The behaviour of the program is undefined, you should fix it and that requires changing the code. You can use the exising conversion operator with static_cast, or you can use your unary * operator idea, which is going to be terser.
Even less change would be required if you used unary + instead which doesn't require introducing an overload, since it will invoke the implicit conversion instead. That may add some confusion to the reader of the code though.
Since you don't want to modify the existing code, you can write a "hack" instead. More specifically, a bunch of overloads to printf() that patch the existing code.
For example:
int printf(const char* f, const SpecialString& a, const SpecialString& b)
{
return printf(f, (const char*)a, (const char*)b);
}
With this function declared in your header, every call to printf() with those specific parameters will use this function instead of the "real" printf() you're familiar with, and perform the needed conversions.
I presume you have quite a few combinations of printf() calls in your code envolving SpecialString, so you may have to write a bunch of different overloads, and this is ugly af to say the least but it does fit your requirement.
As mentioned in another comment, it has always been undefined behavior that happens to work in your case.
With Microsoft CString class, it seems like the undefined behavior was so used (as it happen to work), that now the layout is defined in a way that it will still works. See How can CString be passed to format string %s?.
In our code base, I try to fix code when I modify a file to explicitly do the conversion by calling GetString()
There are a few things you could do:
Fix existing code everywhere you get the warning.
In that case, a named function like c_str or GetString is preferable to a conversion operator to avoid explicit casting (for ex. static_cast or even worst C-style case (const char *). The deref operator might be an acceptable compromise.
Use some formatting library
<iosteam>
fmt: https://github.com/fmtlib/fmt
many other choices (search C++ formatting library or something similar)
Use variadic template function so that conversion could be done.
If you only use a few types (int, double, string) and rarely more than 2 or 3 parameters, defining overloads might also be a possibility.
Not recommended: Hack your class to works again.
Have you done any change to your class definition that cause it to break or only upgrade the compiler version or change compiler options?
Such hack is working with undefined behavior so you must figure out how your compiler works and the code won't be portable.
For it to works the class must have the size of a pointer and the data itself must be compatible with a pointer. Thus essentially, the data must consist of a single pointer (no v-table or other stuff).
Side note: I think that one should avoid defining its own string class. In most case, standard C++ string should be used (or string view). If you need additional functions, I would recommend your to do write stand-alone function in a namespace like StringUtilities for example. That way, you avoid converting back and forth between your own string and standard string (or some library string like MFC, Qt or something else).
According to the top answer to this question, cout << expr is equivalent to cout.operator<<(expr).
According to responses to this question, the statement above is untrue.
According to my own testing, cout.operator<<() is the same as cout << when given an integer. When given a float, cout.operator<<() coerces it to an integer. When given a string literal, as in cout.operator<<("hello world"), it outputs what appears to be a memory address. And when given a variable holding a std::string, it gives a compiler error.
Could anyone give a beginner-to-intermediate-level explanation of what's going on?
It depends on expr.
The answers to both questions are speaking to that specific case, not a blanket guarantee.
In fact, some of the operator<<s are free functions, and some are member functions.
Consult your favourite C++ reference to find out which.
The equivalency of cout << expr and cout.operator<<(expr) depends on what expr is.
If it lands up being a "built in" type, that cout "knows" about, then yes, it is equivalent to cout.operator<<(expr) (a member function).
If it is a "user type" (and std::string counts here), then it is an overloaded non-member method with a signature akin to std::ostream& operator<<(std::ostream&, const std::string&); etc.
Why does cout.operator<<("hello world") print a memory address?
The best member method overload to the above (since it is being forced to use the member method, is ostream& operator<<(const void* value); which outputs the value of the pointer (not what is being pointed to).
By contrast, cout << "hello world" calls the non-member overload ostream& operator<<(ostream&, const char*) and this in-turn inserts each character into the output.
I'm trying to write my own stream class. It will do something with the input and pass it on to std::cout. So far I passed functions operating on the stream (e.g. std::endl) on to cout. Now, I want to check for std::endl input and perform some actions, if it occurs. I have implemented the behaviour like this
DebugStream& DebugStream::operator<< (ostream& (*pfun)(ostream&))
{
if(pfun == std::endl)
{
// do something
}
pfun(cout);
return *this;
}
Which results into
/path/to/file.cpp:89:24: error: assuming cast to type ‘std::basic_ostream<char>& (*)(std::basic_ostream<char>&)’ from overloaded function [-fpermissive]
using the GCC compiler. I don't know, how to compare the function pointer against the std::endl function. Maybe this problem is related to the template nature of the std::endl function? Or because it's inline?
The reason you get a warning is that std::endl is a template function. You can fix this error by forcing a comparison to a template instance of a particular type through a cast, like this:
typedef ostream& (*io_manip_ptr_t)(ostream&);
void demo(io_manip_ptr_t pfun) {
if (pfun == (io_manip_ptr_t)&endl) {
cout << "Hi" << endl;
}
}
Demo.
Note: Even though the work-around is available, this is only a workaround, not a solid solution, because comparing function pointers to decide on functionality introduces a very serious problem: your functions get reduced to an enum, so your code becomes impossible to extend from the outside.
void main() {
cout << "Hello World" << endl;
}
I'm not allowed to make any change to the above main function while the output on the screen need to be sth like:
initialize
Hello World
clean up
My thought is that I need to use overloading operator of << . However I need to know what's the data type of the double quoted string following the operator << , otherwise I will not make full use of my redefined << operator. Anyone any thought?
The type of the literal is "array of {suitable number of} const chars", but a better approach might be to have some kind of global object.
(Adding an overload for the array would probably not even work, because the existing overload for char const * would be getting in the way.)
You could redefine std::ostream& operator<< (std::ostream&, const char*). There's one huge problem with this approach: It is undefined behavior. The standard library already defines that function, and you are not allowed to redefine standard library functions.
The key to solving this problem is to recognize that cout is in the global namespace. The solution is simple: Write your own class that overloads operator<< and make a global variable named cout that is an instance of this class. That way you are not running into undefined behavior.
You'll also need to do something with that endl that is in the global namespace.
Your code should look something like
// Insert your code here.
int main () {
cout << "Hello World" << endl;
}
Since this looks like homework, I'll leave the rest up to you.
The type of a string literal is char const[n] where n is the number of characters in the string literal, including the terminating null character. Note, however, that the solution to your problem isn't overloading operator<<(). Instead, you should look at constructors, destructors, and variable with static live-time.
I am learning operator overloading. "out" is being used instead of "cout" when overloading "<<" operator. I don't understand why.
ostream &operator<<( ostream &out, const IntList &L ) {
out << "[ ";
for (int k=0; k< L.numItems; k++) {
out << L.Items[k] << ' ';
}
out << ']';
}
I want to ask differences between cout and out and what happens if I use cout instead of out.
Thanks for answers.
What you are looking at is a overloaded "stream insertion" operator, allowing some custom class to be written to an ostream object using the typical cout << myObject syntax.
The variable in this case is called out because that's the name they've given to the ostream object being passed into the function, which may be any output stream, whether it's cout or an fstream or a stringstream. It's just a variable name, and they could have called it blah and written:
ostream &operator<<( ostream &blah, const IntList &L ) {
blah << "[ ";
// ...
}
Typically you choose a variable name which is descriptive, and out as a name for an output stream is pretty descriptive.
cout would be an especially bad variable name, as it is strongly associated with std::cout, used for writing specifically to the standard output stream. This code doesn't write specificially to standard output, it writes to any ostream object via the << operator so they've chosen a more generic name for their ostream argument.
I want to ask differences between cout and out and what happens if I use cout instead of out. Thanks for answers.
In this case, an ostream& (out) is a parameter passed to the function. This allows the operator<< to work on any ostream.
cout is a specific ostream instance - the standard output stream. If they used cout here, you wouldn't be able to use the << operator on cerr (the standard error stream) or any other ostream. If you replaced the out with cout in the body, any time you used this on a different ostream, it'd be written to cout. (Of course, if you changed the parameter to be named cout, that wouldn't happen - but it would be very misleading to anybody looking at this code, as people would expect that the code writes to the standard output stream, not to the stream being passed in.)
In general, you only would want to use cout as a name if you are specifically referring to std::cout - the standard output stream, as using it in other contexts would be very confusing.
out is the name of the ostream object passed to the overloaded operator (inside the implementation of the operator).
The overloaded operator allows you to write code like this
IntList i;
cout<<i;
or
cerr<<i;
In the implementation if you substituted out with cout, then the second call
cerr<<i;
would print to standard output whereas it should have printed to standard error.
The critical thing here is really the types in the function signature: as long as it's a freestanding function with two parameters - one of type std::ostream& and the other able to be matched by the value to be streamed, then the function body will be invoked. It should return a reference to the stream to allow chaining (as in if (cout << firstIntList << secondIntList)).
The actual parameter names are whatever you feel like, as long as they're not reserved words. I tend to use "os", as in output-stream.