[英]What is the advantage of Hana's type_c-and-declval dance when querying whether a SFINAE-friendly expression is valid?
一方面,function boost::hana::is_valid
呈现如下
检查 SFINAE 友好的表达式是否有效。
给定一个 SFINAE 友好的 function,
is_valid
返回 function 调用是否对给定的 arguments 有效。 具体来说,给定一个 functionf
和 argumentsargs...
,is_valid(f, args...) == whether f(args...) is valid
结果作为编译时
Logical
返回。
并附带一个使用示例(来自同一链接页面):
struct Person { std::string name; };
auto has_name = hana::is_valid([](auto&& p) -> decltype((void)p.name) { });
Person joe{"Joe"};
static_assert(has_name(joe), "");
static_assert(!has_name(1), "");
我们看到输入给is_valid
的 lambda 反过来又输入了我们输入给 has_name 的实际has_name
。
另一方面, C++ Templates - The Complete Guide一书提出了一个非常相似的解决方案(实际上作者引用了 Boost.Hana和Loius Dionne ),我现在省略了它的细节。 但是,此解决方案的使用方式略有不同:
constexpr auto hasFirst = isValid([](auto x) -> decltype((void)valueT(x).first) {});
static_assert(!hasFirst(type<int>));
struct S { int first; };
static_assert(hasFirst(type<S>));
以上假设存在valueT
和下面定义/声明的type
template<typename T>
struct TypeT {
using Type = T;
};
template<typename T>
constexpr auto type = TypeT<T>{};
template<typename T>
T valueT(TypeT<T>);
现在,如果我理解正确, valueT
和type
大致对应于boost::hana::traits::declval
和boost::hana::type_c
,所以书中的例子应该 map 到以下
constexpr auto hasFirstH = is_valid([](auto x) -> decltype((void)traits::declval(x).first) {});
static_assert(!hasFirst(hana::type_c<int>));
struct S { int first; };
static_assert(hasFirst(hana::type_c<S>));
但这有什么好处呢?
在Louis Dionne 的这个回答中,我最初理解这是一个品味问题,但后来我认为这可能是特定场景的情况,而不是一般情况。
在写这个问题时,我搜索了更多(主要是在其中放置相关链接),我最终在Boost.Hana > User Manual > Introspection > Checking expression validation 的 Boost.Hana 文档中找到了答案> 非静态成员:使用hana::type_c
将类型T
包装在 object 中(不是T
类型,而是hana::type<T>
!)和hana::declval
来解包它是有用的当周围没有 object 时写下这些类型特征。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.