I have a small code snippet which tries to overload "<<" operator of std::cout.
#include<iostream>
using namespace std;
ostream& operator<<(ostream& out,const string& str)
{
out << "overloading" << str << "done";
return out;
}
int main()
{
cout << "string123";
}
output: string123.
It seems my overloading function is not being called. Why?
You're basically shooting yourself in the footin your example. You overload operator<< for std::string type, so you should expect it gets called every time you try to send an "std::string" to out, thus causing runtime stack overlow. To make it work, you:
need to output a char * type to out in operator<< overload, so it doesn't cause infinite recursion
send an actual std::string in main.
Here's a working example without runtime stack overflow problem:
#include<iostream>
using namespace std;
ostream& operator<<(ostream& out, const string& str)
{
out << "overloading" << str.c_str() << "done";
return out;
}
int main()
{
cout << std::string("string123");
}
The output is
overloadingstring123done
First of all, you're not streaming a std::string, but a const char*. You can fix that by writing cout << std::string("string123") instead (demo; although, ew).
Note that there is already such an overload in <string>, and your implementation apparently just go happens to include <string> through <iostream> (as does mine, and as is its prerogative). However, your version (after making the fix above) is a better match since ADL doesn't need to be invoked to find it.
You should send a string type to <<:
ostream& operator<<(ostream& out,const string& str)
{
out<<"overloading";
return out;
}
int main()
{
string s = "string123";
cout << s;
}
Note that sending again the string itself in the << definition will make infinite recursion for
out << "overloading" << str <<"done"
Related
I'd like to know how do stream classes work in C++. When you say:
cout<<"Hello\n";
What does exactly do "<<". I know that cout is an object form iostream that represents the standard output stream oriented to narrow characters (char).
In C "<<" is the bitwise shift operator so it moves bits to the left but in C++ it's and insertion operator. Well, that's all I know, I don't really understand how does this work under the hood.
What I'm asking for is detailed explanation about stream classes in C++, how they are defined and implemented.
Thank you very much for your time and sorry for my English.
Let's create a class that looks like cout (but without as many bells and whistles).
#include <string>
class os_t {
public:
os_t & operator<<(std::string const & s) {
printf("%s", s.c_str());
return *this;
}
};
int main() {
os_t os;
os << "hello\n";
os << "chaining " << "works too." << "\n";
}
Notes:
operator<< is an operator overload just like operator+ or all of the other operators.
Chaining works because we return ourselves: return *this;.
What if you can't change the os_t class because someone else wrote it?
We don't have to use member functions to define this functionality. We can also use free functions. Let's show that as well:
#include <string>
class os_t {
public:
os_t & operator<<(std::string const & s) {
printf("%s", s.c_str());
return *this;
}
};
os_t & operator<<(os_t & os, int x) {
printf("%d", x);
return os;
// We could also have used the class's functionality to do this:
// os << std::to_string(x);
// return os;
}
int main() {
os_t os;
os << "now we can also print integers: " << 3 << "\n";
}
Where else is operator overloading useful?
A great example of how this kind of logic is useful can be found in the GMP library. This library is designed to allow arbitrarily large integers. We do this, by using a custom class. Here's an example of it's use. Note that operator overloading let's us write code that looks almost identical to if we were using the traditional int type.
#include <iostream>
#include <gmpxx.h>
int main() {
mpz_class x("7612058254738945");
mpz_class y("9263591128439081");
x = x + y * y;
y = x << 2;
std::cout << x + y << std::endl;
}
<< is a binary operator in C++, and thus can be overloaded.
You know of the C usage of this operator, where 1 << 3 is a binary operation returning 8. You could think of this as the method int operator<<(int, int) where passing in arguments 1 and 3 returns 8.
Technically, operator<< could do anything. It's just an arbitrary method call.
By convention in C++, the << operator is used for handling streams in addition to being the bit-shift operator. When you perform cout << "Hello!", you are calling a method with prototype ostream & operator<< (ostream & output, char const * stream_me). Note the return value ostream &. That return allows you to call the method multiple times, like std::cout << "Hello World" << "!"; which is calling operator<< twice... once on std::cout and "Hello World", and the second time on the result of that first invocation and "!".
In general, if you were to create a class named class Foo, and you wanted it to be printable, you could define your printing method as ostream & operator<< (ostream & output, Foo const & print_me). Here is a simple example.
#include <iostream>
struct Circle {
float x, y;
float radius;
};
std::ostream & operator<< (std::ostream & output, Circle const & print_me) {
output << "A circle at (" << print_me.x << ", " << print_me.y << ") with radius " << print_me.radius << ".";
}
int main (void) {
Circle my_circle;
my_circle.x = 5;
my_circle.y = 10;
my_circle.radius = 20;
std::cout << my_circle << '\n';
return 0;
}
Operators can be considered functions with syntactic sugar that allow for clean syntax. This is simply a case of operator overloading.
I was practicing some c++ (trying to leave Java), and I stumbled on this annoying error saying:Error: No operater << matches these operands. I've searched this website for a clear answer and no luck, I did find that I'm not the only one.
This error is in my .cpp file, there are other errors, but I'm not paying any mind to them right now.
void NamedStorm::displayOutput(NamedStorm storm[]){
for(int i = 0; i < sizeof(storm); i++){
cout << storm[i] << "\n";
}
}
Something is up with the "<<" im not sure whats going on.
Since you are trying cout a class object you need to overload <<
std::ostream& operator<<(ostream& out, const NamedStorm& namedStorm)
You must overload the << operator in order to redirect your object into a stream.
You can overload as a member function, but in this case you must use the syntax object << stream in order to use that overloaded function.
If you wish to use this syntax stream << object then you must overload the << operator as a 'free' function, that is, not a member of your NamedStorm class.
Here is a working example:
#include <string>
#include <iostream>
class NamedStorm
{
public:
NamedStorm(std::string name)
{
this->name = name;
}
std::ostream& operator<< (std::ostream& out) const
{
// note the stream << object syntax here
return out << name;
}
private:
std::string name;
};
std::ostream& operator<< (std::ostream& out, const NamedStorm& ns)
{
// note the (backwards feeling) object << stream syntax here
return ns << out;
}
int main(void)
{
NamedStorm ns("storm Alpha");
// redirect the object to the stream using expected/natural syntax
std::cout << ns << std::endl;
// you can also redirect using the << method of NamedStorm directly
ns << std::cout << std::endl;
return 0;
}
The function which is called from the free redirection overload must be a public method of NamedStorm (in this case we are calling the operator<< method of the NamedStorm class), OR the redirection overload must be a friend of the NamedStorm class in order to access private fields.
Is it possible to write a method that takes a stringstream and have it look something like this,
void method(string str)
void printStringStream( StringStream& ss)
{
method(ss.str());
}
And can be called like this
stringstream var;
printStringStream( var << "Text" << intVar << "More text"<<floatvar);
I looked up the << operator and it looks like it returns a ostream& object but I'm probably reading this wrong or just not implementing it right.
Really all I want is a clean way to concatenate stuff together as a string and pass it to a function. The cleanest thing I could find was a stringstream object but that still leaves much to be desired.
Notes:
I can't use much of c++11 answers because I'm running on Visual Studio 2010 (against my will, but still)
I have access to Boost so go nuts with that.
I wouldn't be against a custom method as long as it cleans up this mess.
Edit:
With #Mooing Duck's answer mixed with #PiotrNycz syntax I achieved my goal of written code like this,
try{
//code
}catch(exception e)
{
printStringStream( stringstream() << "An exception has occurred.\n"
<<" Error: " << e.message
<<"\n If this persists please contact "<< contactInfo
<<"\n Sorry for the inconvenience");
}
This is as clean and readable as I could have hoped for.
Hopefully this helps others clean up writing messages.
Ah, took me a minute. Since operator<< is a free function overloaded for all ostream types, it doesn't return a std::stringstream, it returns a std::ostream like you say.
void printStringStream(std::ostream& ss)
Now clearly, general ostreams don't have a .str() member, but they do have a magic way to copy one entire stream to another:
std::cout << ss.rdbuf();
Here's a link to the full code showing that it compiles and runs fine http://ideone.com/DgL5V
EDIT
If you really need a string in the function, I can think of a few solutions:
First, do the streaming seperately:
stringstream var;
var << "Text" << intVar << "More text"<<floatvar;
printStringStream(var);
Second: copy the stream to a string (possible performance issue)
void printStringStream( ostream& t)
{
std::stringstream ss;
ss << t.rdbuf();
method(ss.str());
}
Third: make the other function take a stream too
Make your wrapper over std::stringstream. In this new class you can define whatever operator << you need:
class SSB {
public:
operator std::stringstream& () { return ss; }
template <class T>
SSB& operator << (const T& v) { ss << v; return *this; }
template <class T>
SSB& operator << (const T* v) { ss << v; return *this; }
SSB& operator << (std::ostream& (*v)(std::ostream&)) { ss << v; return *this; }
// Be aware - I am not sure I cover all <<'s
private:
std::stringstream ss;
};
void print(std::stringstream& ss)
{
std::cout << ss.str() << std::endl;
}
int main() {
SSB ssb;
print (ssb << "Hello" << " world in " << 2012 << std::endl);
print (SSB() << "Hello" << " world in " << 2012 << std::endl);
}
For ease of writing objects that can be inserted into a stream, all these classes overload operator<< on ostream&. (Operator overloading can be used by subclasses, if no closer match exists.) These operator<< overloads all return ostream&.
What you can do is make the function take an ostream& and dynamic_cast<> it to stringstream&. If the wrong type is passed in, bad_cast is thrown.
void printStringStream(ostream& os) {
stringstream &ss = dynamic_cast<stringstream&>(os);
cout << ss.str();
}
Note: static_cast<> can be used, it will be faster, but not so bug proof in the case you passed something that is not a stringstream.
Since you know you've got a stringstream, just cast the return value:
stringstream var;
printStringStream(static_cast<stringstream&>(var << whatever));
Just to add to the mix: Personally, I would create a stream which calls whatever function I need to call upon destruction:
#include <sstream>
#include <iostream>
void someFunction(std::string const& value)
{
std::cout << "someFunction(" << value << ")\n";
}
void method(std::string const& value)
{
std::cout << "method(" << value << ")\n";
}
class FunctionStream
: private virtual std::stringbuf
, public std::ostream
{
public:
FunctionStream()
: std::ostream(this)
, d_function(&method)
{
}
FunctionStream(void (*function)(std::string const&))
: std::ostream(this)
, d_function(function)
{
}
~FunctionStream()
{
this->d_function(this->str());
}
private:
void (*d_function)(std::string const&);
};
int main(int ac, char* av[])
{
FunctionStream() << "Hello, world: " << ac;
FunctionStream(&someFunction) << "Goodbye, world: " << ac;
}
It is worth noting that the first object sent to the temporary has to be of a specific set of types, namely one of those, the class std::ostream knows about: Normally, the shift operator takes an std::ostream& as first argument but a temporary cannot be bound to this type. However, there are a number of member operators which, being a member, don't need to bind to a reference! If you want to use a user defined type first, you need to extract a reference temporary which can be done by using one of the member input operators.
#include <string>
#include <iostream>
template <typename T>
T max(T a, T b) {
return a > b ? a : b;
}
class Dummy {
private:
std::string name;
int age;
public:
Dummy(int an_age) {age = an_age;}
bool operator> (Dummy &a) {return age > a.age;}
std::string toString() const {return "The age is " + age;}
};
std::ostream& operator<<(std::ostream& out, const Dummy& d) {return out<< d.toString();}
int main()
{
std::cout << max(3, 7) << std::endl;
std::cout << max(3.0, 7.0) << std::endl;
std::cout << max<int>(3, 7.0) << std::endl;
std::cout << max("hello", "hi") << std::endl;
Dummy d1(10);
Dummy d2(20);
std::cout << max(&d1, &d2) << std::endl;
return 0;
}
I'm pretty new to C++ but not new to programming. I've written the code to play with template and operator overloading in C++.
It took quite a while to make it compile and partially work.
The ostream operator<< is not working properly, only to return the address of the object. I can't figure out the causes.
I managed to make it compile by blind trial and error, so I suspect the code might be broken to some extent. And I may not be aware of what'd be improved.
Your max(&d1,&d2) expression gives you the address, and that is printed out. Your operator overloading is fine.
I assume the line you're talking about is
std::cout << max(&d1, &d2) << std::endl;
The problem is you are passing Dummy * instead of Dummy. That makes max return Dummy *, and since your overloaded operator<< takes (essentially) Dummy, it isn't invoked. If you're trying to pass by reference, you don't need to do anything special on the caller side, just make the function take a reference and the compiler will figure it out.
Don't write your own max, use the standard one instead:
#include <algorithm>
void f() { int a = std::max(8, 4); }
The only difference is that the standard max uses operator < by default, just like everything else in the standard library.
Your toString function does something different from what you think it does. It instead returns the sub string of "The age is " starting at the character number age. For example if age is 3, toString will return " age is ". To convert the integer to string you have to use ostringstream:
std::string toString() const {
std::ostringstream s;
s << "The age is " << age;
return s.str();
}
Hey. Is it possible to overload operator<< for primitive types? Fx lets say that I want to write a std::endl each time want to write a int. Can I overload operator<< for int, so that it automatic puts a std::endl to the output? I have tried with this,
std::ostream& operator<<(std::ostream& strm, int & i)
{
strm << i << std::endl;
return strm;
}
but it doesn't work. I cant recall the compiler error message, but I think that I'm getting operator overloading all wrong any ways.
I try to call the above overloaded operator<< in this way,
int main()
{
int i = 2;
std::out<<"Here is an int " << i;
return 0;
}
But it doesn't work at all. Maybe I can't overload POD types?
As zabzonk said, the standard library provides an (ostream&, int) overload so you can't define another.
To simulate what you were doing (though it is completely pointless in its present form :) :
class EndlinedInteger {
public:
EndlinedInteger(int i) : i(i) { }
friend ostream& operator<<(ostream&, EndlinedInteger const&);
private:
int i;
};
ostream& operator<<(ostream& out, EndlinedInteger const& ei) {
out << ei.i << endl;
return out;
}
int main()
{
EndlinedInteger i = 2;
std::cout<<"Here is an int " << i;
}
Remember that here you use << operator not only on int but also on ostream. You could derive from ostream and implement it in your own derived class, but I would suggest to make a simple macro like
#define EL(i) (i)<<std::endl
Alternatively you could make boxed int class and override the << for standard ostream and boxed int (like in answer by Iraimbilanja) class. Sounds like huge overkill but could work.
Your problem is that there is already an overload for operator << (ostream &, int), the one supplied by the C++ standard library. If you remove the overload definition and use:
#include <iostream>
int main()
{
int i = 2;
std::out<<"Here is an int " << i;
return 0;
}
things work as expected.
And BTW, compiler error messages are kind of important, so it's a good idea to remember them and quote them in posts when asking questions.
edit - std::out above should of couse be std::cout