ostream插入操作符与其非成员重载之间的关系 [英] Relation between ostream insertion operator and its non-member overload

查看:210
本文介绍了ostream插入操作符与其非成员重载之间的关系的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

1,非成员重载(两个参数,一个是ostream,另一个是操作数,say int)在std命名空间中定义。因此,如果使用命名空间std; 不存在,我没有办法看到非成员重载可以被调用。



2,如果相反,成员运算符(ostream的成员;一个参数,是操作数的类型,说int)function<的ostream被调用,我会期望像: std :: cout.operator<<



那么,两者之间的关系究竟是什么呢?



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



a)<$ c $流动&运算符<< MyType obj);





b)in MyType:

  class MyType 
{
...
ostream& ;运算符<< (MyType);
};

选项b)有效吗?它甚至有意义(我记得看到它在某个地方...)?选项a)和选项a)之间的关系是什么? b)




$ b


EDIT MAR 27 b

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

  #include< iostream> 

namespace MyNameSpace
{
class MyType
{};

//签名可以在这里找到:http://www.cplusplus.com/reference/ostream/ostream/operator-free/
std :: ostream& operator<<<(std :: ostream& out,char ch)
{
out< std is doomed\\\
;
return out;
}

std :: ostream& operator<<<(std :: ostream& out,MyType t)
{
out< std is super doomed\;
return out;
}
}

int main()
{
MyNameSpace :: MyType t;
std :: cout<< t; // ... super doomed; ADL正按预期工作。
std :: cout<< 't'; // t;这证明当有两个具有相同签名但在不同命名空间中的运算符重载时,没有编译错误。 gcc默认为std。
return 0;
}


解决方案

思考的是字符数据 std :: string 等。;则可通过 参数相关查找 。你可以为 std :: cout.operator<<(i) / basic_ostream / operator_ltltrel =nofollow>其中 ostream 具有成员运算符<<



对于你自己的类型,你想到一个(非成员)朋友运算符<< ,这对于模板类( Barton-Nackman trick )或者运算符<< 访问通过访问器无法访问的数据:

 code> class MyType 
{
...
friend std :: ostream&运算符<< (std :: ostream&,MyType obj){...}
};

您建议的签名将允许您写 my_obj< my_obj ,这是不太可能有什么意义。


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

1, The non-member overload(two arguments, one being ostream& the other being type of operand, say int) is defined in std namespace. So if using namespace std; is not present, there's no way I see that the non-member overload can be called.

2, If instead, the member operator(member of ostream; one argument, being the type of operand, say int) function << of ostream is called, I'd expect something like: std::cout.operator<< i; --- isn't this rediculous?

So, what on earth is the relation between the two?

Question extended: if I want to overload the insertion operator so that std::cout << my_obj; works(assume my_obj is the instance of a user-defined type, MyType), should I do

a) ostream& operator<< (ostream& os, MyType obj); in the namespace of MyType

or

b) in MyType:

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

does option b) ever work? Does it even make sense(I remember seeing it somewhere ...)? What's the relation between option a) & b)?


EDIT MAR 27

Upon the request from ecatmur, here're two overloads that have the same signature but in different namespaces. Using 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;
}

解决方案

The non-member overloads you're thinking of are those for character data and those for std::string etc.; they're available via argument-dependent lookup. You can indeed write std::cout.operator<<(i) for types where ostream has a member operator<<.

For your own types you're thinking of a (non-member) friend operator<<, which can be particularly useful for template classes (the Barton-Nackman trick) or for those where the operator<< accesses data not available via accessors:

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

Your proposed signature would allow you to write my_obj << my_obj, which is unlikely to make much sense.

这篇关于ostream插入操作符与其非成员重载之间的关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆