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).
The <
operator must be in any of the associated namespaces of it parameters, i.e it must be in either namespace n1
or n2
but since n2::tag
is not visible at the definition of n1::tag
you need to place the operator in namespace n2
or reopen the namespace n1
.
defining the operator in 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);
}
}
opening namespace 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);
}
}