我正在努力将用户定义的类型作为hana::map
. 我遇到一种static_assert
说法,即必须在编译时进行比较。我确实实现constexpr bool operator==
了(我相信)所有这些的组合。有什么问题?由于 my operator==
is constexpr
,我的对象应该在编译时具有可比性,对吧?
问问题
291 次
1 回答
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
从该参数中提取 a,即使Key
已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==
返回一个IntegralConstant
. 这里和这里有更多关于这个和相关概念的信息。
于 2015-10-19T17:32:37.397 回答