开发者

Overloading I/O operator C++

I'm trying to overload the << operator. I'm expecting the output to be Initializing开发者_StackOverflowHello 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");
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜