超载左移操作员

Ash*_*h K 5 c++ operator-overloading argument-dependent-lookup

我已经研究过并发现当你想为cout重载输出流操作符时,那么正确的方法是这样做:

std::ostream& operator<<(std::ostream& os, const T& obj)
Run Code Online (Sandbox Code Playgroud)

这个函数必须在类之外定义,因为这里发生的是操作符<<实际上是ostream中定义的友元函数,你正在使用它.但是,问题是,这个函数究竟是如何在ostream中定义的?由于此函数需要2个参数,而第二个参数是用户定义的,因此他们无法猜出将要发生什么.

特定类的重载应如下所示:

std::ostream& operator<<(std::ostream& os, const MyClass& obj)
Run Code Online (Sandbox Code Playgroud)

编译器/库如何为第二个参数采用泛型定义,特别是因为在C++中没有泛型类(如Java中的Object)这样的东西?

Kon*_*lph 8

我觉得你很困惑:

operator <<实际上是ostream中定义的友元函数,你正在利用它.

确实在内部定义了一个 .实际上,它内部定义了几个版本.但那些与我们无关.此外,它们不是函数:根据定义,函数在类之外被定义为它的朋友.operator <<class std::ostreamfriendfriend

但这与您定义的函数无关,因为您的operator <<函数是一个单独的重载,当您将类型的对象作为第二个参数传递给<<(第一个参数为a std::ostream&)时,将调用该函数.

正如TemplateRex所解释的那样,找到适当函数的确切方法是通过参数依赖查找.但更基本的是,您只需要知道有两种方法可以为给定的参数类型定义二元运算符,A并且B:

  • 作为类中的成员函数A,并且只有一个类型的参数B
  • 作为一个带有两个参数的自由函数,类型AB.

当您使用运算符时,这两个定义都是候选函数.(但是有几个运算符,例如复制赋值只能在类中定义,而不能在外部定义).所以,回到你的问题:

这个函数究竟是如何在ostream中定义的?由于此函数需要2个参数,而第二个参数是用户定义的,因此他们无法猜出将要发生什么

答案是它没有定义ostream.唯一的定义是你的,它在外面.