首页 > 解决方案 > Comparison operator for std::optional enum

问题描述

According to this, using a comparison operator on an optional<T> and optional<U> should work provided that the same operator is defined for the underlying types T and U.

I am trying out the following example with two enums defined in different namespaces (live code here) and can't figure out why it fails to compile:

#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);
}

My GCC-8.2.0 says that:

invalid operands to binary expression ('const std::optional<n1::tag>' and 'const std::optional<n2::tag>')

Any ideas? I've found out that moving each enum out of their namespaces, things work as expected (as here).

标签: c++c++17optionalcomparison-operators

解决方案


运算符必须在它参数的<任何关联命名空间中,即它必须在命名空间中,n1或者n2但由于n2::tag在定义时不可见,因此n1::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);
    }        
}

推荐阅读