c++ - Why does decltype(declval<T>().func()) work where decltype(&T::func) doesn't? -
i trying detect presence of member function baz() in template parameter:
template<typename t, typename = void> struct implementsbaz : public std::false_type { }; template<typename t> struct implementsbaz<t, decltype(&t::baz)> : public std::true_type { }; but produces false:
struct foo {}; struct bar { void baz() {} }; std::cout << implementsbaz<foo>::value << std::endl; // 0 std::cout << implementsbaz<bar>::value << std::endl; // 0 using declval , calling method work, though:
template<typename t> struct implementsbaz<t, decltype(std::declval<t>().baz())> : public std::true_type { }; of course, can detect baz function 0 arguments. why specialization correctly selected when using declval<t>().baz(), not decltype(&t::baz)?
if use void_t "detection idiom", does work expected:
template <typename...> using void_t = void; template <typename t> struct implementsbaz<t, void_t<decltype(&t::baz)>> : std::true_type {}; struct bar { void baz() {} }; static_assert(implementsbaz<bar>::value); // passes as why, this question explains in detail how "void_t trick" works. quote accepted answer:
it's if had written
has_member<a, void>::value. now, template parameter list compared against specializations of templatehas_member. if no specialization matches, definition of primary template used fall-back.
in original case, decltype(&t::baz) not void, specialization not match original template , not considered. need use void_t (or other mechanism, such cast) change type void specialisation used.
Comments
Post a Comment