如何实现 Boost.Hana 结构的相等比较运算符?



假设我们有 Boost.Hana Struct:

struct SomeStruct {
BOOST_HANA_DEFINE_STRUCT(SomeStruct, (int, x), (double, y), (char, c));
};

我想将SomeStructs1 == s2s1 != s2进行比较.

如果我将两个运算符都添加到结构定义中,例如

struct SomeStruct {
BOOST_HANA_DEFINE_STRUCT(SomeStruct, (int, x), (double, y), (char, c));
constexpr bool operator == (SomeStruct const& other) {
return boost::hana::equal(*this, other);
}
constexpr bool operator != (SomeStruct const& other) {
return boost::hana::not_equal(*this, other);
}
};

代码将无法编译,因为SomeStruct变得既StructEqualityComparable

像这样的解决方案

struct SomeStruct {
BOOST_HANA_DEFINE_STRUCT(SomeStruct, (int, x), (double, y), (char, c));
constexpr bool operator == (SomeStruct const& other) {
return boost::hana::equal(boost::hana::members(*this),
boost::hana::members(other));
}
constexpr bool operator != (SomeStruct const& other) {
return boost::hana::not_equal(boost::hana::members(*this),
boost::hana::members(other));
}
};

将工作,直到SomeStruct内部没有嵌套的Hana结构(具有相同的operator==()operator!=()实现(。

定义 Boost.Hana 结构的相等比较运算符的正确方法是什么?

更新: 我需要相等比较运算符而不是boost::hana::equal()SomeStruct因为,例如,std::optional<SomeStruct>对象的相等比较需要它们。

你不能。我在Boost.Hana的Github上为此做了一个问题(https://github.com/boostorg/hana/issues/460(

如果您真的希望它现在工作,您可以专门针对您的类型boost::hana::detail::EqualityComparable来解决此问题。

#include <boost/hana.hpp>
namespace hana = boost::hana;
struct SomeStruct {
BOOST_HANA_DEFINE_STRUCT(SomeStruct, (int, x), (int, y), (char, c));
constexpr bool operator == (SomeStruct const& other) {
return boost::hana::equal(boost::hana::members(*this),
boost::hana::members(other));
}
constexpr bool operator != (SomeStruct const& other) {
return boost::hana::not_equal(boost::hana::members(*this),
boost::hana::members(other));
}
};
// horrible workaround
namespace boost::hana::detail {
template <>
struct EqualityComparable<SomeStruct> : std::false_type { };
}
int main() {
// OK
static_assert(SomeStruct{5, 5, 5} == SomeStruct{5, 5, 5});
// FAIL (ambiguous template instantiation with detail::EqualityComparable
//       without horrible workaround)
static_assert(hana::equal(SomeStruct{5, 5, 5}, SomeStruct{5, 5, 5}));
}

https://godbolt.org/z/Eu64Ng

我认为你可以用SomeStructWrapper来包装你的SomeStruct,它作为成员SomeStruct,并在其operator==()operator!=()调用boost::haha::equal()

struct SomeStructWrapper
{
SomeStruct someStruct;
constexpr bool operator == (SomeStructWrapper const& other) 
{
return boost::haha::equal(this->someStruct, other.someStruct);
}
};

你不能将二元运算符定义为自由函数吗?

#include <boost/hana.hpp>
struct SomeStruct {
BOOST_HANA_DEFINE_STRUCT(SomeStruct, (int, x), (double, y), (char, c));
};
constexpr bool operator == (SomeStruct const& some, SomeStruct const& other) {
return boost::hana::equal(boost::hana::members(some),
boost::hana::members(other));
}
constexpr bool operator != (SomeStruct const& some, SomeStruct const& other) {
return boost::hana::not_equal(boost::hana::members(some),
boost::hana::members(other));
}

最新更新