非会员运营商超载应该放在哪里?

Pra*_*ian 16 c++ namespaces operator-overloading

我想operator<<为我的班级超载.我应该将这个重载的定义添加到std命名空间吗?(因为它ostream operator<<std命名空间的一部分)或者我应该把它留在全局命名空间中?

简而言之:

class MyClass {

};

namespace std {
    ostream& operator<< ( ostream& Ostr, const MyClass& MyType ) {}
}
Run Code Online (Sandbox Code Playgroud)

要么

class MyClass {

};

std::ostream& operator<< ( std::ostream& Ostr, const MyClass& MyType ) {}
Run Code Online (Sandbox Code Playgroud)

哪个更合适,为什么?在此先感谢您的回复.

Jam*_*lis 28

您应该将运算符重载放在与您的类相同的命名空间中.

这将允许在使用依赖于参数的查找的重载解析期间找到运算符(实际上,因为ostream在命名空间中std,如果将它放在命名空间中也会发现重载重载std,但是没有理由这样做).

从良好的设计实践来看,运算符重载更多是类接口的一部分,而不是接口ostream,因此它与您的类属于同一个命名空间(另请参阅Herb Sutter的命名空间和接口原理).

从编写符合标准且可移植的代码的角度来看,您不能将运算符重载放入命名空间std.虽然您可以将用户定义的实体的模板特化添加到命名空间std,但您无法添加其他函数重载.

  • @chubsdad:是的,我想是的:你_can_添加专业化; 你_can't_添加重载. (3认同)

Sam*_*ler 7

不要将它添加到std命名空间,将其放在与您的类相同的命名空间中.命名空间的目的是防止冲突.标准说

17.4.3.1保留名称

除非另有说明,否则C++程序未定义向命名空间std中的命名空间std或命名空间添加声明或定义.程序可以将任何标准库模板的模板特化添加到命名空间std.标准库模板的这种特化(完整或部分)会导致未定义的行为,除非声明取决于用户定义的外部链接名称,除非特化符合原始模板的标准库要求.


Car*_*arl 6

不要添加到标准命名空间.原因:如果每个人都这样做,标准命名空间就会有大量的名称冲突,这会破坏命名空间的目的.

您的目标是让您的班级"ostream-able".它不需要在标准命名空间中执行此操作.只要你的班级被宣布为任何名称,你就没事了.将它放在标准命名空间中将是不好的做法.