static_assert 在 hana 教程中使用非 constexpr 对象

static_assert with nonconstexpr objects in hana's tutorial

正在阅读 hana's tutorial,我想知道 static_assert 如何按预期工作:

template <typename Any>
auto switch_(Any& a) {
  return [&a](auto ...cases_) {
    auto cases = hana::make_tuple(cases_...);

    auto default_ = hana::find_if(cases, [](auto const& c) {
      return hana::first(c) == hana::type_c<default_t>;
    });

    static_assert(default_ != hana::nothing,
      "switch is missing a default_ case");

    // ...
  };
}

文档明确指出 default_ 不是 constexpr 对象,因此,即使这些类型的 operator!= 重载是 constexpr 函数,表达式 default_ != hana::nothing 不能是常量表达式,因为它的参数之一不是。

教程说:

Notice how we can use static_assert on the result of the comparison with nothing, even though default_ is a non-constexpr object? Boldly, Hana makes sure that no information that's known at compile-time is lost to the runtime, which is clearly the case of the presence of a default_ case.

教程在该段中指的是什么,或者该表达式是如何工作的?

您误解了 constexpr 的要求。您可以将非 constexpr 参数传递给 constexpr 函数,结果 可以 constexpr.

玩具示例:

struct foo {
  int x;
  foo(int in):x(in){}
  friend constexpr bool operator==(foo const&, foo const&) { return true; }
};

然后

foo a{1}, b{2};
static_assert( a==b, "works" );

完全有效。

哎呀,我可以在堆上分配那些 foo,并且 == 仍然会计算为 constexpr 表达式。

default_ 不是 constexpr,但仅使用 [=20= 的 type 信息就可以将其与 nothing 进行比较],在编译时可用。没有什么比得上 hana::nothing 但(另一个实例)没有。

struct toy_nothing_t {
  friend constexpr bool operator==(toy_nothing_t const&, toy_nothing_t const&) {
    return true;
  }
  template<class T>
  friend constexpr bool operator==(T const&, toy_nothing_t const&) {
    return false;
  }
  template<class T>
  friend constexpr bool operator==(toy_nothing_t const&, T const&) {
    return false;
  }
};

这个 toy_nothing_t 具有相似的属性。