2

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

4

1 回答 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,即使Keyconstexpr 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 回答