简体   繁体   中英

overloading left shift operator

I have researched and found out that when you want to overload the output stream operator for cout, then the correct way to go about it is to do it this way:

std::ostream& operator<<(std::ostream& os, const T& obj)

This function must be defined outside the class since whats going on here is that the operator<< is actually a friend function defined in ostream and you are making use of that. But, the question is, how exactly is this function being defined in ostream? Since this function takes 2 parameters and the second parameter is user-defined, there is no way that they can guess what is coming there.

Overloading for a class specific should look like this:

std::ostream& operator<<(std::ostream& os, const MyClass& obj)

How does the compiler/library take a generic definition for the second parameter, especially since there is no such thing as a generic class (such as Object in Java) in C++?

I think you are confused here:

the operator<< is actually a friend function defined in ostream and you are making use of that.

It's true that an operator << is defined inside class std::ostream . In fact, there are several versions defined inside it. But those don't concern us. Furthermore, they are not friend functions: By definition, a friend function is defined outside the class it is a friend of.

But this is all unrelated to the function you defined, because your operator << function is a separate overload which is being called when you pass an object of your type as the second argument to an invocation of << (the first argument being a std::ostream& ).

As TemplateRex has explained, the exact way of finding the appropriate function is via argument-dependent lookup. But more fundamentally, you simply need to know that there are two ways of defining a binary operator for given argument types A and B :

  • As a member function inside class A , and having only one argument, of type B
  • As a free function with two arguments, of types A and B .

Both these definitions are candidate functions when you use the operator. (But there are several operators, such as copy assignment which can only be defined inside the class, not outside). So, coming back to your question:

how exactly is this function being defined in ostream? Since this function takes 2 parameters and the second parameter is user-defined, there is no way that they can guess what is coming there

The answer is that it is not defined in ostream . The only definition is yours, and it's outside.

C++ functions can be overloaded , ie multiple functions with the same name but taking different arguments can co-exist. The compiler goes through a three-step process of Name Lookup, Argument-Deduction and Overload Resolution. At the end of that, only a single function overload can survive as the best match. A gentle introduction to these concepts can be gotten from the first three videos in the series Core C++ by Stephan T. Lavavej .

A common case is a user-defined class S inside a namespace N (which could be the global one) with an operator<<(ostream&, S const&) overload inside that same namespace.

namespace N {

class S 
{
    // bla
};

std::ostream& operator<<(std::ostream& os, S& const& obj)
{
    // print in terms of public interface of S
    // (else, deckare this a friend function inside S)
    return os;
}

} // N

int main()
{
    std::cout << S(); // operator<<(ostream&, S const&) is the best match
}

Name lookup is subtle, in this case it works through so-called argument dependent lookup , which looks in namespaces associated to function arguments. For the above code, these namespace are std (where all the Standard Library functions live) and N (where your overload operator<<(ostream&, S const&) lives). Argument deduction will deduce the correct type, and overload resolution will find that your overload is the best match (in this case, in all likelihood the only match).

Hence, the ability to print your user-defined types using "native" syntax.

NOTE : in this case, it's not called the "left-shift" operator but the "stream insertion" operator, even though the latter has the same lexical form as the former.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM