【问题标题】:Namespaces and Operator Overloading in C++C++ 中的命名空间和运算符重载
【发布时间】:2010-09-15 08:55:04
【问题描述】:

在特定命名空间中编写库时,为该命名空间中的类提供重载运算符通常很方便。似乎(至少在 g++ 中)重载的运算符可以在库的命名空间中实现:

namespace Lib {
class A {
};

A operator+(const A&, const A&);
} // namespace Lib

或全局命名空间

namespace Lib {
class A {
};
} // namespace Lib

Lib::A operator+(const Lib::A&, const Lib::A&);

根据我的测试,它们似乎都可以正常工作。这两个选项之间有什么实际区别吗?哪种方法更好?

【问题讨论】:

标签: c++ operator-overloading namespaces


【解决方案1】:

您应该在库命名空间中定义它们。 编译器无论如何都会通过参数相关查找找到它们。

无需污染全局命名空间。

【讨论】:

  • 使用库命名空间的另一个原因:this post 包含一个使用全局命名空间不起作用的示例。
【解决方案2】:

由于Koenig lookup,将其放入库命名空间是可行的。

【讨论】:

  • 确实 Koeing 查找是完全创建的,因此您可以将函数放在 Lib 命名空间中,并且仍然让它重载正确。请参阅异常 C++ 项 31-32。
【解决方案3】:

您应该在命名空间中定义它,因为语法不会那么冗长,而且不会使全局命名空间混乱。

实际上,如果您在类定义中定义重载,这将成为一个没有实际意义的问题:

namespace Lib {

class A {
public:
    A operator+(const A&);
};

} // namespace Lib

【讨论】:

  • 这可能是个坏主意,因为这意味着如果 B 可以隐式转换为 A 但不是 A 的子类,那么 A+B 可以工作,但 B+A 令人困惑的是不能。当然这并不重要,例如,如果您的房屋风格无论如何都禁止用户定义类型之间的隐式转换。
  • 我同意:存在 A+B 有效但 B+A 无效的问题(假设 A 是模拟复数的类,而 B 是 int)。另一个问题是非友元运算符+函数增加了类的封装,而类方法减少了它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-03
  • 1970-01-01
  • 2019-06-18
  • 2015-04-26
  • 2019-02-05
  • 1970-01-01
相关资源
最近更新 更多