【问题标题】:Defining compile-time Comparable objects with Boost.Hana使用 Boost.Hana 定义编译时 Comparable 对象
【发布时间】:2016-01-18 03:39:21
【问题描述】:

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

【问题讨论】:

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


    【解决方案1】:

    您必须从比较运算符返回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[]内部,返回值的type取决于key。我们必须以某种方式提取一个bool,表示哪个值与该键相关联,但是bool 必须在编译时已知(即是一个常量表达式),以便返回类型依赖于它。所以在operator[] 内部,我们需要一个constexpr bool 来表示key 是否是与给定映射值关联的键。但是,由于无法指定keyconstexpr 参数这一事实,因此我们无法从该参数中提取constexpr bool,即使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。有更多关于这个和相关概念的信息herehere

    【讨论】:

      猜你喜欢
      • 2018-05-13
      • 1970-01-01
      • 2021-09-16
      • 1970-01-01
      • 2014-04-27
      • 2021-12-26
      • 2012-08-16
      • 2023-03-10
      • 2016-04-25
      相关资源
      最近更新 更多