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