23 January 2023

C++ 核心指南目录

“Define overloaded operators in the namespace of their operands”

理由

更好的可读性。可以使用 ADL 查找操作符。避免在不同名字空间中定义的不一致。

例子

struct S { };
S operator+(S, S);   // OK: in the same namespace as S, and even next to S
S s;

S r = s + s;

例子

namespace N {
    struct S { };
    S operator+(S, S);   // OK: in the same namespace as S, and even next to S
}

N::S s;

S r = s + s;  // finds N::operator+() by ADL

坏例子

struct S { };
S s;

namespace N {
    bool operator!(S a) { return true; }
    bool not_s = !s;
}

namespace M {
    bool operator!(S a) { return false; }
    bool not_s = !s;
}

此处, !s 的意思在名字空间 N 和 M 中不一样。这样会导致很大的困惑。

注意

如果操作数是在不同的名字空间里的两个不同的对象,那就无法遵循这条规则了。

比如

Vec::Vector operator*(const Vec::Vector&, const Mat::Matrix&);

不过这种情况最好还是避免发生。

强化

  • 标注和操作数不在一个名字空间的操作符。