c++ - std::optional 枚举的比较运算符

标签 c++ c++17 option-type comparison-operators

根据 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>')

有什么想法吗?我发现将每个枚举移出它们的命名空间,一切都按预期工作(如 here )。

最佳答案

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

在命名空间 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);
    }        
}

关于c++ - std::optional 枚举的比较运算符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52917842/

相关文章:

c++ - c++17 中 std::destroy_at() 的用法?

ios - 输入字符串或字符时应用程序崩溃

c++ - Arduino内存泄漏

c++ - Friend函数无法构造类的唯一指针

c++ - 在 C++ 程序中访问 Apple Magic Trackpad 输入数据

c++ - 有没有办法在 std::string_view 迭代器上使用 std::remove_if ?

c# - 如何在 c# 中的内存中直接一个接一个地创建结构?

c++ - 模板化参数中仿函数的默认参数

java - 如何设置Maven项目选择性生成签名文件

java - 过滤特定cookie的cookie数组并获取Java中特定cookie的值