简体   繁体   English

boost.Hana中何时<> trait的工作原理如何?

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

I have some experience with std::enable_if . 我对std::enable_if有一些经验。 IIRC, it is about if a well-formed expression results in true return back the user type T (if given) or void via nested type alias. 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*");

But in boost.Hana I see this trait when<> and its implementation is like 但是在boost.Hana中,当<>及其实现就像时,我看到了这个特性

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*

How the SFINAE works here? SFINAE如何在这里工作? though the std::is_integral<some>::value is going to result in false, it doesn't mean(it does?) that the when<false> is ill-formed and should dispatch the instantiation to the primary class template. 虽然std::is_integral<some>::value将导致false,但它并不意味着(确实如此?) when<false>ill-formed并且应该将实例化分派给主类模板。 Am I missing anything here? 我在这里错过了什么吗?

It's the same general idea. 这是一般的想法。 You can use enable_if_t or decltype in basically the same way. 您可以以基本相同的方式使用enable_if_tdecltype Now, you're probably used to seeing SFINAE partial specializations like this: 现在,你可能习惯于看到像这样的SFINAE部分特化:

template<class T, class U = void>
struct Foo {};

template<class T>
struct Foo<T, decltype(T::bar())> {};

... Foo<X> ...

Here, Foo<X> is first expanded by the compiler to Foo<X, void> (because you didn't provide U at the "call site", so the default U = void is filled in instead). 这里, Foo<X>首先被编译器扩展为Foo<X, void> (因为你没有在“调用站点”提供U ,所以默认的U = void被填入)。 Then, the compiler looks for the best-matching specialization of class template Foo . 然后,编译器查找类模板Foo的最佳匹配特化。 If decltype(X::bar()) is in fact void , then Foo<T, decltype(T::bar())> [with T=X] will be a perfect match for Foo<X, void> . 如果decltype(X::bar())实际上是void ,那么Foo<T, decltype(T::bar())> [with T=X]将是Foo<X, void>的完美匹配。 Otherwise, the generic Foo<T, U> [with T=X, U=void] will be used instead. 否则,将使用通用Foo<T, U> [with T=X, U=void]

Now for the Hana when example. 现在的花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> ...

Here, Foo<X> is first expanded by the compiler to Foo<X, when<true>> (because you didn't provide U at the "call site", so the default U = when<true> is filled in instead). 这里, Foo<X>首先被编译器扩展为Foo<X, when<true>> (因为你没有在“调用站点”提供U ,所以默认的U = when<true>被填入时代替)。 Then, the compiler looks for the best-matching specialization of class template Foo . 然后,编译器查找类模板Foo的最佳匹配特化。 If when<X::baz> is in fact when<true> , then Foo<T, when<T::baz>> [with T=X] will be a perfect match for Foo<X, when<true>> . 如果when<X::baz>实际上是when<true> ,那么Foo<T, when<T::baz>> [with T=X]将是Foo<X, when<true>>的完美匹配Foo<X, when<true>> Otherwise, the generic Foo<T, U> [with T=X, U=when<true>] will be used instead. 否则,将使用通用Foo<T, U> [with T=X, U=when<true>]时。

You can replace the simple expression T::baz in my example with any arbitrarily complicated boolean expression, as long as it's constexpr-evaluable. 您可以将我的示例中的简单表达式T::baz替换为任意复杂的布尔表达式,只要它是constexpr-evaluable即可。 In your original example, the expression was std::is_integral<T>::value . 在您的原始示例中,表达式为std::is_integral<T>::value

My CppCon 2017 session "A Soupçon of SFINAE" walks through some similar examples. 我的CppCon 2017年会议“SFINAE的Soupçon”演示了一些类似的例子。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM