使用Boost.Hana定义编译时Comparable对象

时间:2015-10-19 17:24:58

标签: c++ metaprogramming c++14 boost-hana

我正在努力将用户定义的类型作为hana::map中的键。 我遇到static_assert说我必须在比较中进行比较 编译时间。我确实为组合实现了constexpr bool operator== (我相信)所有这些。问题是什么?由于我的operator==constexpr,我的对象在编译时应该具有可比性,对吗?

1 个答案:

答案 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是否是与给定地图值相关联的关键字。但是,由于无法指定keyconstexpr参数这一事实,我们无法从该参数中提取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==。有关此信息及相关概念的更多信息herehere