Reputation: 6626
I have re-implemented boost::hana::is_valid
for study purpose. The use case is:
struct Person {
std::string name;
};
int main()
{
auto has_name = is_valid([](auto&& t) -> decltype((void) t.name) {});
Person jon{"snow"};
static_assert(has_name(jon), "");
static_assert(!has_name(1), "");
}
Implementation:
namespace detail {
template<typename F>
struct is_valid_impl {
template<typename T, typename = std::result_of_t<F&&(T&&)>>
constexpr bool operator()(T&&) const noexcept { return true; }
constexpr bool operator()(...) const noexcept { return false; }
};
} // namespace detail
template<typename F>
constexpr auto is_valid(F&&)
{
return detail::is_valid_impl<F>{};
}
However, I don't know why Hana's user guide recommends casting the type of the wanted member to void
(see here); can't we just use decltype(t.name)
instead of decltype((void) t.name)
?
Moreover, the cast to void
causes the tests to fail in GCC < 5.3, while without the cast the code works for GCC 5.1+. What could be the reason?
Upvotes: 4
Views: 172
Reputation: 43662
Can't be more explicit than the documentation:
@snippet example/tutorial/introspection.cpp non_static_member_from_object
Notice how we cast the result of
x.member
tovoid
? This is to make sure that our detection also works for types that can't be returned from functions, like array types.
Upvotes: 2