根据this的介绍,如果为基础类型optional<T>optional<U>定义了相同的运算符,则可以对TU使用比较运算符。

我正在尝试以下示例,并在不同的命名空间(实时代码here)中定义了两个枚举,但无法弄清楚为什么它无法编译:

#include <optional>

namespace n1
{
    enum class tag : unsigned {I,II,III};
}

namespace n2
{
    enum class tag : unsigned {I,II,III};
}

bool operator<(const n1::tag& t1, const n2::tag& t2)
{
    return static_cast<unsigned>(t1) < static_cast<unsigned>(t2);
}

int main()
{
    const std::optional<n1::tag> o1(n1::tag::I);
    const std::optional<n2::tag> o2(n2::tag::I);
    bool t = (o1 < o2);
}

我的GCC-8.2.0说:
invalid operands to binary expression ('const std::optional<n1::tag>' and 'const std::optional<n2::tag>')
有任何想法吗?我发现将每个枚举移出其 namespace 后,一切都会按预期进行(如here)。

最佳答案

<运算符必须位于其参数的任何关联命名空间中,即它必须位于命名空间n1n2中,但是由于n2::tagn1::tag的定义中不可见,因此您需要将运算符放在命名空间n2中或重新打开命名空间n1

在 namespace n2中定义运算符:

namespace n2
{
    enum class tag : unsigned {I,II,III};
    bool operator<(const n1::tag& t1, const n2::tag& t2)
    {
        return static_cast<unsigned>(t1) < static_cast<unsigned>(t2);
    }
}

打开命名空间n1:
...

namespace n2
{
    enum class tag : unsigned {I,II,III};
}
namespace n1 {
    bool operator<(const n1::tag& t1, const n2::tag& t2)
    {
        return static_cast<unsigned>(t1) < static_cast<unsigned>(t2);
    }
}

10-08 09:41
查看更多