ostream 插入运算符与其非成员重载之间的关系


int i=0;
std::cout << i;

1,非成员重载(两个参数,一个是ostream,另一个是操作数类型,比如int(在std命名空间中定义。因此,如果using namespace std;不存在,则我无法看到可以调用非成员重载。

2,如果相反,调用成员

运算符(ostream的成员;一个参数,作为操作数的类型,比如int(函数<<ostream,我希望像这样:std::cout.operator<< i; ---这不是可笑吗?

那么,两者之间到底是什么关系呢?

扩展问题:如果我想重载插入运算符以使std::cout << my_obj;工作(假设my_obj是用户定义类型MyType的实例(,我应该这样做

a( 在 MyType 的命名空间中ostream& operator<< (ostream& os, MyType obj);

b( 在 MyType 中:

class MyType
{
 ...
   ostream& operator<< (MyType);
};

选项 B( 是否有效?它甚至有意义吗(我记得在某处看到过它......选项 a( 和 b( 之间的关系是什么?


编辑三月 27

根据 ecatmur 的请求,这里有两个具有相同签名但位于不同命名空间中的重载。使用 gcc 4.9.2:http://melpon.org/wandbox/

#include <iostream>
namespace MyNameSpace
{
    class MyType
    {};
    // signature can be found here: http://www.cplusplus.com/reference/ostream/ostream/operator-free/
    std::ostream& operator<<(std::ostream& out, char ch)
    {
        out << "std is doomedn";
        return out;
    }
    std::ostream& operator<<(std::ostream& out, MyType t)
    {
        out << "std is super doomedn";
        return out;
    }
}
int main()
{
    MyNameSpace::MyType t;
    std::cout << t; // ... super doomed; ADL is working as intended.
    std::cout << 't'; // t; this proves that when there're two operator overloads with the same signature but in different namespaces, there're no compilation errors. gcc defaults to the std one.
    return 0;
}

您正在考虑的非成员重载是用于字符数据和用于std::string等的非成员重载;它们可以通过依赖于参数的查找获得。 您确实可以为ostream具有成员operator<<的类型编写std::cout.operator<<(i)

对于您自己的类型,您正在考虑(非成员(friend operator<<,这对于模板类(Barton-Nackman 技巧(或operator<<访问无法通过访问器获得的数据的类特别有用:

class MyType
{
 ...
   friend std::ostream& operator<< (std::ostream&, MyType obj) { ... }
};

提议的签名将允许你写my_obj << my_obj,这不太可能有太大意义。

最新更新