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

How do I implement equality compare operators for Boost.Hana Structs?

假设我们有 Boost.Hana 结构:

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 结构定义相等比较运算符的正确方法是什么?

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

我想你可以用 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));
}

你不能。我为此 (https://github.com/boostorg/hana/issues/460)

在 Boost.Hana 的 Github 上提出了一个问题

如果您真的希望它现在可以工作,您可以针对您的类型专门化 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