如何何时<>性状在提升。哈娜工作?

How the when<> trait in boost.Hana works?

本文关键字:哈娜 工作 lt 何何时 gt      更新时间:2023-10-16

我对std::enable_if有一些经验。IIRC,它是关于格式正确的表达式是否导致true通过嵌套类型别名返回用户类型 T(如果给定(或 void。

template<bool,typename = void>
struct enable_if;
template<typename T>
struct enable_if<true,T>{
using type = T;
};
template <typename T, typename = void>
struct base_template{
enum { value= false};
};
template <typename T>
struct base_template<T, typename enable_if<std::is_integral<T>::value>::type> {
enum { value= true};// something useful...
};
struct some{};
static_assert(base_template<some>::value,"F*"); //error: static assertion failed: F
static_assert(base_template<int>::value,"F*");

但在提升。哈纳 我看到这个特质的时候<>它的实现就像

template <bool condition>
struct when;
template <typename T, typename = when<true>>
struct base_template{
enum { value= false};
};
template <typename T>
struct base_template<T, when<std::is_integral<T>::value>> {
enum { value= true};// something useful...
};
struct some{};
static_assert(base_template<int>::value,"F*");
static_assert(base_template<some>::value,"F*");<source>:28:15: error: static assertion failed: F*

SFINAE 在这里是如何工作的? 尽管std::is_integral<some>::value将导致 false,但这并不意味着(确实如此?(when<false>ill-formed并且应该将实例化调度到主类模板。我在这里错过了什么吗?

这是相同的一般想法。您可以以基本相同的方式使用enable_if_tdecltype。现在,您可能已经习惯于看到SFINAE的部分专业化,如下所示:

template<class T, class U = void>
struct Foo {};
template<class T>
struct Foo<T, decltype(T::bar())> {};
... Foo<X> ...

在这里,编译器首先将Foo<X>扩展到Foo<X, void>(因为您没有在"调用站点"提供U,因此会填写默认U = void(。然后,编译器查找类模板Foo的最佳匹配专用化。如果decltype(X::bar())实际上是void,那么Foo<T, decltype(T::bar())> [with T=X]将是Foo<X, void>的完美匹配。否则,将改用通用Foo<T, U> [with T=X, U=void]

现在以哈纳when为例。

template<bool> struct when {};
template<class T, class U = when<true>>
struct Foo {};
template<class T>
struct Foo<T, when<T::baz>> {};
... Foo<X> ...

在这里,编译器首先将Foo<X>扩展到Foo<X, when<true>>(因为您没有在"调用站点"提供U,因此会填写默认U = when<true>(。然后,编译器查找类模板Foo的最佳匹配专用化。如果when<X::baz>实际上是when<true>,那么Foo<T, when<T::baz>> [with T=X]将是Foo<X, when<true>>的完美匹配。否则,将改用泛型Foo<T, U> [with T=X, U=when<true>]

您可以将我示例中T::baz的简单表达式替换为任何任意复杂的布尔表达式,只要它是 constexpr-evalue。在您的原始示例中,表达式std::is_integral<T>::value

我的CppCon 2017会议"SFINAE的汤"介绍了一些类似的例子。