【发布时间】:2022-09-17 03:13:47
【问题描述】:
一方面,函数boost::hana::is_valid呈现如下
检查 SFINAE 友好的表达式是否有效。
给定一个对 SFINAE 友好的函数,
is_valid返回给定参数的函数调用是否有效。具体来说,给定一个函数f和参数args...,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的实际对象。另一方面,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,所以书中的示例应该映射到以下内容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>));但这有什么好处呢?
在this answer from Louis Dionne 我最初理解这是一个品味问题,但后来我认为可能是这种情况对于那个特定的场景而不是一般。
标签: c++ c++17 template-meta-programming sfinae boost-hana