如何为 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));
};
我想将 SomeStruct
与 s1 == s2
和 s1 != 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
变成了 Struct
和 EqualityComparable
。
类似的解决方案
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}));
}
假设我们有 Boost.Hana 结构:
struct SomeStruct {
BOOST_HANA_DEFINE_STRUCT(SomeStruct, (int, x), (double, y), (char, c));
};
我想将 SomeStruct
与 s1 == s2
和 s1 != 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
变成了 Struct
和 EqualityComparable
。
类似的解决方案
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
.
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}));
}