我正在努力将用户定义的类型作为hana::map
中的键。
我遇到static_assert
说我必须在比较中进行比较
编译时间。我确实为组合实现了constexpr bool operator==
(我相信)所有这些。问题是什么?由于我的operator==
是constexpr
,我的对象在编译时应该具有可比性,对吗?
答案 0 :(得分:3)
您必须从比较运算符返回integral_constant<bool, ...>
,而不是constexpr bool
。以下作品:
#include <boost/hana.hpp>
#include <cassert>
#include <string>
namespace hana = boost::hana;
template <int i>
struct UserDefined { };
template <int a, int b>
constexpr auto operator==(UserDefined<a>, UserDefined<b>)
{ return hana::bool_c<a == b>; }
template <int a, int b>
constexpr auto operator!=(UserDefined<a>, UserDefined<b>)
{ return hana::bool_c<a != b>; }
int main() {
auto m = hana::make_map(
hana::make_pair(UserDefined<0>{}, std::string{"zero"}),
hana::make_pair(UserDefined<1>{}, 1)
);
assert(m[UserDefined<0>{}] == "zero");
assert(m[UserDefined<1>{}] == 1);
}
<强>为什么吗
要理解为什么constexpr bool
比较运算符不够,请考虑hana::map::operator[]
的伪实现:
template <typename ...implementation-defined>
struct map {
template <typename Key>
auto operator[](Key const& key) {
// what now?
}
};
在operator[]
内,返回值的类型取决于键。我们必须以某种方式提取表示哪个值与该键相关联的bool
,但必须在编译时知道bool
(即为常量表达式),以使返回类型依赖于该值。因此,在operator[]
内,我们需要constexpr bool
来表示key
是否是与给定地图值相关联的关键字。但是,由于无法指定key
是constexpr
参数这一事实,我们无法从该参数中提取constexpr bool
,即使Key
有{ {1}}已定义。换句话说,
constexpr bool operator==
实现上述目标的唯一方法是执行类似
的操作template <typename Key>
auto operator[](Key const& key) {
// impossible whatever some_other_key_of_the_map is
constexpr bool found = (key == some_other_key_of_the_map);
// return something whose type depends on whether the key was found
}
因此要求template <typename Key>
auto operator[](Key const& key) {
constexpr bool found = decltype(key == some_other_key_of_the_map)::value;
// return something whose type depends on whether the key was found
}
返回Key::operator==
。有关此信息及相关概念的更多信息here和here。