ostream插入操作符与其非成员超载之间的关系

时间:2015-03-27 17:02:15

标签: c++ c++11 stream operator-overloading c++-standard-library

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

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

2,相反,如果成员运算符(ostream的成员;一个参数,是操作数的类型,比如int)函数&lt;&lt;喧嚣被称为,我期待的是: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)&amp;的关系是什么? B)?


编辑MAR 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 doomed\n";
        return out;
    }

    std::ostream& operator<<(std::ostream& out, MyType t)
    {
        out << "std is super doomed\n";
        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;
}

1 个答案:

答案 0 :(得分:1)

您想要的非成员超载是those for character datathose for std::string etc.;他们可以通过argument-dependent lookup获取。您确实可以为types where ostream has a member operator<<撰写std::cout.operator<<(i)

对于您自己的类型,您考虑的是(非成员)friend operator<<,这对模板类(Barton-Nackman trick)或{{1}的用户特别有用访问通过访问器不可用的数据:

operator<<

您提议的签名将允许您编写class MyType { ... friend std::ostream& operator<< (std::ostream&, MyType obj) { ... } }; ,这不太可能有意义。