2010-09-02 59 views
13

我想为我的班级重载operator<<。我应该将这个重载的定义添加到std命名空间吗? (因为ostream operator<<std命名空间的一部分)或者我应该把它留在全局命名空间中吗?非成员运算符重载应该放在哪里?

简而言之:

class MyClass { 

}; 

namespace std { 
    ostream& operator<< (ostream& Ostr, const MyClass& MyType) {} 
} 

OR

class MyClass { 

}; 

std::ostream& operator<< (std::ostream& Ostr, const MyClass& MyType) {} 

哪个更合适,为什么?预先感谢您的回复。

回答

25

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

这将允许使用参数相关查找(当然,实际上,因为ostream是在命名空间std,过载超载也将如果你把它命名空间std发现重载解析过程中发现的运营商,但有没有理由这样做)。

从良好设计实践的角度来看,操作符重载比类接口ostream更接近类接口的一部分,因此它与您的类属于相同的命名空间(另请参阅Herb Sutter的Namespaces and the Interface Principle)。

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

+1

+1此外,强制性链接:http://en.wikipedia.org/wiki/Argument-dependent_lookup – 2010-09-02 03:31:16

+0

考虑到山姆对标准的回应和引用,最后一句是否真正正确。 – Chubsdad 2010-09-02 03:46:20

+3

@chubsdad:是的,我认为是这样的:你可以增加专业化;你不能添加重载。 – 2010-09-02 03:48:51

6

不要添加到标准名称空间。 原因:如果每个人都这样做了,那么标准名称空间就会有大量名称冲突,这会破坏名称空间的用途。

你的目标是让你的班级成为“ostream-able”。它不需要在标准名称空间中进行。只要它在你的班级宣布的任何名称中,你都很好。将它放入标准名称空间将是不好的做法。

+1

它破坏了用于C++标准库代码的'std'命名空间的目的。哪个用户代码不是。 – 2010-09-02 03:32:00

6

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

17.4.3.1保留名称

这是未定义一个C++程序 除非另有规定 内 空间std添加声明或定义, std命名空间或命名空间。程序可以将任何标准 库模板的 专用模板添加到名称空间标准。的未定义的行为 一个标准库 模板结果 这种专业化(完全或 部分),除非声明取决于外部联动 的 用户定义的名称和,除非专门满足 为 原始标准库的要求模板。