【问题标题】:Where should non-member operator overloads be placed?非成员运算符重载应该放在哪里?
【发布时间】:2011-04-07 02:55:26
【问题描述】:

我想为我的班级重载operator<<。我应该将此重载定义添加到std 命名空间吗? (因为ostream operator<<std 命名空间的一部分)还是应该将其留在全局命名空间中?

简而言之:

class MyClass {

};

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

class MyClass {

};

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

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

【问题讨论】:

    标签: c++ namespaces operator-overloading


    【解决方案1】:

    不要添加到标准命名空间。 原因:如果每个人都这样做,标准命名空间会产生大量名称冲突,这违背了命名空间的目的。

    您的目标是让您的班级“支持直播”。它不需要在标准名称空间中执行此操作。只要它在您的类声明的任何名称空间中,就可以了。将它放在标准命名空间中是不好的做法。

    【讨论】:

    • 它违背了 std 命名空间的目的,它是用于 C++ 标准库代码的。哪个用户代码不是。
    【解决方案2】:

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

    17.4.3.1 保留名称

    对于 C++ 程序来说,它是未定义的 添加声明或定义到 命名空间标准或命名空间内 命名空间 std 除非另有说明 指定的。一个程序可以添加模板 任何标准的专业化 库模板到命名空间 std。 这样的专业化(完整或 部分)标准库 模板导致未定义的行为 除非声明依赖于 自定义外部链接名称 除非专业满足 标准库要求 原始模板。

    【讨论】:

      【解决方案3】:

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

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

      从良好设计实践的角度来看,运算符重载更多是类接口的一部分而不是ostream 的接口,因此它与您的类属于同一命名空间(另请参见 Herb Sutter 的 Namespaces and the Interface Principle )。

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

      【讨论】:

      • 考虑到 Sam 的回应和引用标准,最后一句话真的正确吗?
      • @chubsdad:是的,我想是的:你可以添加专业;你不能添加重载。
      • 如果您想为 std 中的类添加重载(例如 std::nullptr_t、std::unique_ptr 等)怎么办?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-30
      • 2011-06-05
      • 2013-11-29
      相关资源
      最近更新 更多