[英]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_t
或decltype
。 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.