C++中的命名空间和运算符重载

42

在特定命名空间中编写库时,为该命名空间中的类提供重载运算符通常很方便。似乎(至少在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&);

通过我的测试,这两种方法看起来都可以很好地工作。这两个选项之间是否存在实际差异?哪种方法更好?


可能是命名空间和运算符解析的重复问题。 - user9645477
3个回答

41

你应该在库的命名空间中定义它们。 编译器会通过参数相关查找自动找到它们。

不需要污染全局命名空间。


5
使用库命名空间的另一个原因是:这篇帖子中包含一个例子,其中使用全局命名空间无法正常工作。 - Tim

17
将其放入库命名空间中可行,因为有Koenig查找的存在。

1
确实,Koeing查找是专门为了让您将函数放在Lib命名空间中,并仍然正确地进行重载而创建的。请参见《Exceptional C++》第31-32项。 - tenpn

2

应该在命名空间中定义它,这样语法会更简洁,不会使全局命名空间混乱。

实际上,如果你在类定义中定义了重载函数,这个问题就变得无关紧要了:

namespace Lib {

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

} // namespace Lib

2
这可能是一个坏主意,因为这意味着如果B可以隐式转换为A但不是A的子类,那么A + B可以工作,但B + A会令人困惑。当然,如果您的编码规范禁止用户定义类型之间的隐式转换,那就无关紧要了。 - Steve Jessop
2
我同意:存在这样的问题,即A+B可以工作,但B+A不行(假设A是模拟复数的类,而B是整数)。另一个问题是非友元运算符+会增加类的封装性,而类方法会降低它。 - paercebal

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接