Thomas
Thomas

Reputation: 182000

Why can I overload istream's operator>> for strings?

Suppose I wanted operator>> to extract entire lines from an istream instead of whitespace-separated words. I was surprised to see that this, although horrible, actually worked:

#include <iostream>
#include <string>

namespace std {
  istream &operator>>(istream &is, string &str) {
    getline(is, str);
  }
}

int main() {
  std::string line;
  std::cin >> line;
  std::cout << "Read: '" << line << "'\n";
}

If I type multiple words into stdin, it actually does call my operator and read an entire line.

I would expect this definition of operator>> to conflict with the official one, producing a link error. Why doesn't it?


Edit: I thought maybe the real operator>> was a template, and non-template functions take precedence, but this still works just as well:

namespace std {
  template<typename charT>
  basic_istream<charT> &operator>>(basic_istream<charT> &is, basic_string<charT> &s) {
    getline(is, s);
  }
}

Upvotes: 1

Views: 107

Answers (1)

Jan Hudec
Jan Hudec

Reputation: 76316

It happens to work because the official template is less specific (there are additional template arguments).

However it is Undefined Behaviour™. You are only permitted to provide overloads of standard library symbols for your own types. If you come across another standard library that will define extra overloads (it may), it will stop working and you won't know why.

Upvotes: 3

Related Questions