I'm trying to overload the << operator. I'm expecting the output to be InitializingHello WorldOut but it is just outputting Hello World. I can't figure out what is wrong with my code. Thanks for your help.
#include <iostream>
using namespace std;
ostream &operator << (ostream &out, const char* &s)
{
out << "Initializing" << s << "Out";
return out;
}
void main() {
cout << "Hello World" << endl;
system("Pause");
}
"Hello World" is actually of type const char[12], which can decay into an r-value (temporary) of type const char *, but your function takes a reference to a const char*, and as you may know, you cannot bind a reference to a non-const r-value. So your operator is not called, but instead the standard ostream &operator << (ostream &out, const char* s) is.
PS. Please do not write void main(). It should be int main() unless you are in an embedded system (not likely).
There already is an overload for << with the exact same prototype. The compiler cannot decide which to use...
There is already a operator<< for const char* defined in the standard library, which is used in the output. Your overload is not used because the temporary string literal cannot be bound to the non-const reference in the operators second parameter.
If you remove the reference or make it const, then your operator is called. It doesn't even conflict with the one in your standard library, since that one is implemented as a function template. Yours is not, and non-templated functions are preferred by the compiler.
If it is then called, it leads to a stack overflow because out << "Initializing" immediately calls the same operator again recursively.
rodrigo pointed out that the type of a string literal is const char[x], and I had an evil idea:
#include <iostream>
using namespace std;
template<int len>
ostream &operator << (ostream &out, const char (&s)[len])
{
out << ((const char*)"Initializing") << ((const char*)s) << ((const char*)"Out");
return out;
}
int main() {
cout << "Hello World" << endl;
}
http://ideone.com/7wCNy
I think that since the left hand side is in the std namespace, it's using the function ostream& std::operator << (ostream &out, const char* s) that's defined in the std namespace instead of yours in the global namespace. If you were to try to put yours into the std namespace, you'd get a linker error. Your only real hope is to change the types of one side or the other, probably by making a wrapper around them.
struct charptr {
const char* ptr;
charptr(const char* p) :ptr(p) {}
};
ostream &operator << (ostream &out, const charptr &s)
{
out << "Initializing" << s.ptr << "Out";
return out;
}
int main() { //int main, not void
cout << charptr("Hello World") << endl;
system("Pause");
}
Related
I'm trying to overload the << when it receives a string. I want that if the string is lets say Mark, it prints instead Dog. I know it doesn't make sense for you but this is what I need.
I've tried this but it does not work.
std::ostream& operator << (std::ostream &out, string& a);
std::ostream& operator << (std::ostream &out, string& a){
std::cout << "I love dogs";
return out;
}
int main(){
std::cout<<"I love cats";
return 0;
}
I want it to change every single string no matter where I use the function std::cout << string and for it to instead printing what String is, it would always print Dog instead.
My problem is that instead of printing Dog, it keeps on printing the string given. Like it keeps printing I love cats instead of I love dogs
I already tried:
std::ostream& operator << (std::ostream &out, const char* a){
std::cout << "I love dogs";
return out;
}
Instead but it give me segmentation fault.
std::ostream& operator << (std::ostream &out, const char* &a);
And this one keeps on printing I love cats
You have to ensure that your custom operator<< will call the default operator and not call itself. You can do this by using a namespace qualifier on the overloaded operator (std::operator<<). Also, string literals are const char [] and not std::string.
#include <iostream>
std::ostream &operator<<(std::ostream &os, const char *) {
return std::operator<<(os, "I love dogs\n");
}
int main() {
std::cout << "I love cats\n";
}
You should embrace your code with a namespace std for a properly defined operator<<(...) method for iostream.
#include <iostream>
namespace std {
std::ostream &operator<<(std::ostream &os, const char *) {
return std::operator<<(os, "I love dogs\n");
}
}
int main() {
std::cout << "I love cats\n";
}
I have learnt the operator<< can be overloaded by making it a friend function of class.
For example,
struct Test
{
std::string d_data;
Test(const std::string & data) : d_data{data} {}
friend std::ostream & operator<<(std::ostream & ostr, const Test & obj)
{
ostr << obj.d_data << '\n';
return ostr;
}
};
int main()
{
Test t1("one");
std::cout << t1;
Test t2("two");
std::cout << t2;
}
one
two
This seems to work as expected.
But, I'm unable to understand why the same isn't working for a global overload.
#include <iostream>
#include <ostream>
#include <string>
std::ostream & operator<<(std::ostream & os, const std::string & s)
{
os << s << '\n';
return os;
}
int main()
{
std::cout << "stackoverflow";
std::cout << "stackoverflow";
}
stackoverflowstackoverflow
Expected the strings to be separated by a newline, but didn't work as expected.
Your operator using
std::cout << "stackoverflow";
requires a user-defined conversion from an object of the type const char * (after the implicit conversion of the string literal to pointer to its first character) to an object of the type std::string.
However the standard basic_ostream class has already an operator that does not require such a conversion
template<class charT, class traits>
basic_ostream<charT, traits>& operator<<(basic_ostream<charT, traits>&, const char*);
So this operator is called instead of your operator.
Moreover within your operator
std::ostream & operator<<(std::ostream & os, const std::string & s)
{
os << s << '\n';
return os;
}
there is recursive calls of itself.
Your could define your operator the following way
#include <iostream>
#include <string>
std::ostream & operator<<(std::ostream & os, const char *s)
{
return std::operator <<( os, s ) << '\n';
}
int main()
{
std::cout << "stackoverflow";
std::cout << "stackoverflow";
}
and get the expected result
stackoverflow
stackoverflow
Note that "stackoverflow" is of type const char[], but not std::string. That means your overload won't be invoked, but the one from standard library (operator<<(std::basic_ostream) is invoked, because it's an exact match and doesn't require the implicit conversion from const char[] to std::string.
template< class Traits >
basic_ostream<char,Traits>& operator<<( basic_ostream<char,Traits>& os,
const char* s );
BTW: It could be found because of ADL.
You can overload globally, but "stackoverflow" is not a std::string, so yours isn't used.
(And there already is such an overload in the standard library.)
To see that it works, move your first overload out of the class definition and make it a non-friend.
The only reason it has to be declared friend is that you have declared it inside the class definition, so it would be a member function otherwise.
This will work as you expect:
struct Test
{
std::string d_data;
Test(const std::string & data) : d_data{data} {}
};
std::ostream & operator<<(std::ostream & ostr, const Test & obj)
{
ostr << obj.d_data << '\n';
return ostr;
}
int main()
{
Test t1("one");
std::cout << t1;
Test t2("two");
std::cout << t2;
}
I just wondering why this code is incorrect ? It constantly call Foo constructor and cause stack overflow after sometime.
#include <iostream>
using namespace std;
class Foo
{
std::string str;
public:
Foo(const string& s) : str(s)
{
cout << "Foo constructor" << endl;
}
friend ostream& operator<<(ostream& os,const Foo& foo);
};
ostream& operator<<(ostream& os,const Foo& foo)
{
os << foo.str;
return os;
}
int main()
{
Foo foo{"Hello"};
cout << foo;
cin.get();
}
I know, I know it is ok to write
cout << foo.str << endl;
or os << foo.str.c_str();
but I want to know why this error happens..
The program use std::string and its output operator but does not include the header <string>: when using <string> you need to include that header. The fact that std::string seems to be defined by including <iostream> is insufficient. It is also not portable: a different implementation may choose to only declare but not defined std::string (a declaration is needed, though, as some IOStream members to use the type std::string).
If the output operator for std::string isn't found, the expression
out << foo.str
is interpreted as as
out << Foo(foo.str)
as there is an output operator for Foo. Of course, that does result in an infinite recursion.
I have some problems in understanding the << operator.
If I have:
#include <iostream>
using namespace std;
//...
int t = 5;
cout << "test is: " << t << endl;
Now the function operator<< is called.
ostream& operator<<(ostream& out, string* s)
{
return out << s << endl;
}
ostream& operator<<(ostream& out, int* value)
{
return out << value << endl;
}
the string-pointer points to the address with value test is: but to what does the element out refer (to cout?)? and is the function body of ostream& correct in that way?
Thank you so much for any explanation.
First, let's fix your code: the operators should be taking const references or values instead of pointers:
ostream& operator<<(ostream& out, const string& s) // const reference
ostream& operator<<(ostream& out, int i) // value
Now to your question: you are correct, the out parameter receives the reference to the cout, or whatever is the ostream& returned from the expression on the left side of <<. The expression on the left of << is not necessarily cout, though - other common cases are results of other << operators* for chaining, and stream manipulators. In all cases these expressions return a reference to ostream so that the "chain" could continue.
* The reason the operator<< return an ostream& is so that you could chain the output. In overwhelming number of cases you wold return the same ostream& that you receive as the first parameter, although there is no limitation on the part of the standard C++ library requiring you to do that.
int t = 5;
cout << "test is: " << t << endl;
First call would be to:-
ostream& operator<<(ostream& out, const char* str)
out = cout
str = "test is: "
Second call would be applied on object returned by first call which is ostream.
ostream& operator<<(ostream& out, int x)
out = cout
x = t
This is not true. It's int not int*, and char const* not string*.
out, of course, refers to std::cout in this example. What else would it be?
And no those bodies are not correct in the slightest — they attempt to reinvoke themselves infinitely, and do nothing else.
I am trying to create my own std::string wrapper to extend its functionality.
But I got a problem when declaring the << operator.
Here's my code so far:
my custom string class:
class MyCustomString : private std::string
{
public:
std::string data;
MyCustomString() { data.assign(""); }
MyCustomString(char *value) { data.assign(value); }
void Assign(char *value) { data.assign(value); }
// ...other useful functions
std::string & operator << (const MyCustomString &src) { return this->data; }
};
the main program:
int main()
{
MyCustomString mystring("Hello");
std::cout << mystring; // error C2243: 'type cast' : conversion from 'MyCustomString *' to 'const std::basic_string<_Elem,_Traits,_Ax> &' exists, but is inaccessible
return 0;
}
I wanted cout to treat the class as a std::string, so that I won't need to do something like:
std::cout << mystring.data;
Any kind of help would be appreciated!
Thanks.
Just fyi: my IDE is Microsoft Visual C++ 2008 Express Edition.
If you look at how all stream operators are declared they are of the form:
ostream& operator<<(ostream& out, const someType& val );
Essentially you want your overloaded function to actually do the output operation and then return the new updated stream operator. What I would suggest doing is the following, note that this is a global function, not a member of your class:
ostream& operator<< (ostream& out, const MyCustomString& str )
{
return out << str.data;
}
Note that if your 'data' object was private, which basic OOP says it probably should, you can declare the above operator internally as a 'friend' function. This will allow it to access the private data variable.
You need a free-standing function (friend of your class, if you make your data private as you probably should!)
inline std::ostream & operator<<(std::ostream &o, const MyCustomString&& d)
{
return o << d.data;
}
Firstly, you seem to have an issue with the definition of MyCustomString. It inherits privately from std::string as well as containing an instance of std::string itself. I'd remove one or the other.
Assuming you are implementing a new string class and you want to be able to output it using std::cout, you'll need a cast operator to return the string data which std::cout expects:
operator const char *()
{
return this->data.c_str();
}
That's not how you overload the << operator. You need to pass in a reference to an ostream and return one (so you can stack multiple <<, like std::cout << lol << lol2).
ostream& operator << (ostream& os, const MyCustomString& s);
Then just do this:
ostream& operator << (ostream& os, const MyCustomString& s)
{
return os << s.data;
}