重载左移位运算符
overloading left shift operator
我已经研究并发现,当您想要重载输出流操作符为cout时,那么正确的方法是这样做:
std::ostream& operator<<(std::ostream& os, const T& obj)
这个函数必须在类之外定义,因为这里的操作符<<实际上是ostream中定义的友元函数,你正在使用它。但是,问题是,这个函数到底是如何在ostream中定义的?因为这个函数有两个参数,第二个参数是用户自定义的,所以他们无法猜测这里会发生什么。
特定类的重载应该如下所示:
std::ostream& operator<<(std::ostream& os, const MyClass& obj)
编译器/库如何采用第二个参数的泛型定义,特别是因为在c++中没有泛型类(如Java中的Object)这样的东西?
我想你是搞混了:
operator<& lt;实际上是ostream中定义的友元函数,你正在使用它。
确实和 operator <<
在class std::ostream
中被定义。实际上,它内部定义了几个版本。但这些与我们无关。而且,它们不是friend
函数:根据定义,friend
函数定义在类之外。
但是这与你定义的函数无关,因为你的operator <<
函数是一个独立的重载,当你将你的类型的对象作为第二个参数传递给<<
调用时(第一个参数是std::ostream&
),它被调用。
正如TemplateRex所解释的那样,查找适当函数的确切方法是通过依赖于参数的查找。但更基本的是,您只需要知道为给定参数类型A
和B
定义二进制操作符有两种方式:
- 作为
A
类内部的成员函数,并且只有一个参数,类型为B
- 作为一个自由函数,有两个参数,类型为
A
和B
。
当使用操作符时,这两个定义都是候选函数。(但是有几个操作符,比如拷贝赋值,只能在类内部定义,不能在类外部定义)。那么,回到你的问题:
这个函数是如何在ostream中定义的?因为这个函数有两个参数,第二个参数是用户自定义的,所以他们无法猜出里面是什么
答案是不是在ostream
中定义的。唯一的定义是你的,它在外面。
c++函数可以重载,即多个具有相同名称但采用不同参数的函数可以共存。编译器要经历三个步骤:名称查找、参数推导和重载解析。最后,只有一个函数重载可以作为最佳匹配而存在。这些概念的简单介绍可以从Stephan T. Lavavej Core c++系列的前三个视频中获得。
一个常见的情况是用户定义的类S
在命名空间N
中(可以是全局的),在同一个命名空间中有一个operator<<(ostream&, S const&)
重载。
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
}
名称查找很微妙,在本例中,它通过所谓的参数依赖查找工作,查找与函数参数关联的名称空间。对于上面的代码,这些命名空间是std
(所有标准库函数所在的地方)和N
(您的重载operator<<(ostream&, S const&)
所在的地方)。参数推导将推导出正确的类型,重载解析将发现您的重载是最佳匹配(在本例中,很可能是唯一匹配)。
因此,能够使用"本机"语法打印用户定义的类型。
:在这种情况下,它不是"左移"操作符,而是"流插入"操作符,尽管后者与前者具有相同的词法形式。
- 使用boost::multiprecision cpp_int左移时出现超时错误
- 警告:左移计数 >= 在 C++ 中将字节流读取为双精度变量时的类型宽度
- 左移<<如何在不同的功能中给出不同的结果?
- 使用 AVX2 指令左移 128 位数字
- <<(按位左移)在 Swift 中的数组上做什么?
- 带有左移操作员C 的意外输出
- 编译器将输出的流运算符<<解释为用于按位左移的二进制运算符<<
- 左移负整数为零是否有意义?
- 在 VS 移位中,UINT64 上的左移(64 >移位> 32)位仅 32 位
- C++20 是否为"overflow"的有符号整数很好地定义了左移?
- C++左移操作
- 为什么编译器左移 0
- 如何在位明智的操作中选择正确的左移
- 虽然左移运算符 (<<) 在 std::cout 之前使用,但它有什么用?
- 使用左移运算符将 F 转换为 FF
- 重载左移和右移运算符(cin和cout)
- 重载运算符'<<'(左移)的显式专用化
- 奇怪的积分提升用左移运算符
- 何时使用运算符<<指插入运算符,何时指按位左移
- 测试左移运算符是否存在