c++ - How does std::invoke(C++1z) work? -
namespace detail { template <class f, class... args> inline auto invoke(f&& f, args&&... args) -> decltype(std::forward<f>(f)(std::forward<args>(args)...)) { return std::forward<f>(f)(std::forward<args>(args)...); } template <class base, class t, class derived> inline auto invoke(t base::*pmd, derived&& ref) -> decltype(std::forward<derived>(ref).*pmd) { return std::forward<derived>(ref).*pmd; } template <class pmd, class pointer> inline auto invoke(pmd pmd, pointer&& ptr) -> decltype((*std::forward<pointer>(ptr)).*pmd) { return (*std::forward<pointer>(ptr)).*pmd; } template <class base, class t, class derived, class... args> inline auto invoke(t base::*pmf, derived&& ref, args&&... args) -> decltype((std::forward<derived>(ref).*pmf)(std::forward<args>(args)...)) { return (std::forward<derived>(ref).*pmf)(std::forward<args>(args)...); } template <class pmf, class pointer, class... args> inline auto invoke(pmf pmf, pointer&& ptr, args&&... args) -> decltype(((*std::forward<pointer>(ptr)).*pmf)(std::forward<args>(args)...)) { return ((*std::forward<pointer>(ptr)).*pmf)(std::forward<args>(args)...); } } // namespace detail template< class f, class... argtypes> decltype(auto) invoke(f&& f, argtypes&&... args) { return detail::invoke(std::forward<f>(f), std::forward<argtypes>(args)...); }
i saw implementation above here:
http://en.cppreference.com/w/cpp/utility/functional/invoke
then wonder how compilers match exact version required. sfinae work on trailing return type?
does sfinae work on tailing return type?
yes. trailing return type syntax doesn't enable new functionality, merely makes easier write cases of return types depend on parameter types.
template <class f, class... args> inline auto invoke(f&& f, args&&... args) -> decltype(std::forward<f>(f)(std::forward<args>(args)...) { ... }
could have equivalently been written as
template <class f, class... args> inline decltype(std::forward<f>(std::declval<f&>())(std::forward<args>(std::declval<args&>())...)) invoke(f&& f, args&&... args) { ... }
for instance, , same others. simplified, if simplify it, fact return type cannot use same syntax return
expression makes hard follow what's going on. hence new syntax.
the time sfinae doesn't work deduced return types. use auto
, it's not auto
keyword disables sfinae.
Comments
Post a Comment