c++ - For type modification traits, should I provide a template-typedef (aka using) convenience wrapper for typename::transform<...>::type? -
i wondering availability of template-typedefs should provide convenience wrappers classes transform types. consider (useless) example:
template< t > struct whatever { typedef typename std::conditional< sizeof(t) <= sizeof(void*), int, long >::type type; }; here, std::conditional transform title, used typename transform<...>::type. also, whatever transform , used in same way.
with availability of template-typedefs (aka using), change interface to:
template< t > using whatever = typename std::conditional< sizeof(t) <= sizeof(void*), int, long >::type; which simplifies usage. done cases, due required (partial) specialization, end implementation class , wrapper. in case of std::conditional, you'd end moving std::impl::conditional<...> , provide wrapper as
namespace std { namespace impl { // "classic" implementation of std::conditional } template< bool b, typename t, typename f > using conditional = typename impl::conditional< b, t, f >::type; } this leaves question interface/api should provide. see 1 strong point providing wrapper: prevents user errors. see example this question & answer.
for keeping existing interface, see following points:
- consistency. that's type traits , using
- separation of transformer , result of transformation. can pass transformer type, in case of
whateverabove, wouldn't possible anymore. - less code preventing
implsolution required specializations.
i'd hear arguments or against providing "new" interface, not merely opinions "i second approach better". i'm interested in finding out cases 1 or other approach required or when fails work/scale.
to honest, question lack of experience template-typedefs, if have real-world experience, please shared , bad side of , whether or not should consider typename transform<...>::type api obsolete c++11 or not.
i following:
- inside namespace (impl, detail, etc.) have classes real work.
- outside, have template aliases clean calling code.
for example, if re-write std::remove_reference, following:
namespace detail { template <typename t> struct remove_reference { using type = t; }; template <typename t> struct remove_reference<t&> { using type = t; }; template <typename t> struct remove_reference<t&&> { using type = t; }; } template <typename t> using remove_reference = typename detail::remove_reference<t>::type; i didn't compile above code, don't shoot me if made typo.
a benefit calling site more clear. 1 potential drawback if writing higher order generic code , rely on existence of ::type inside of type function, e.g.
template <template <typename...> class f, typename... ts> using apply = typename f<ts...>::type; though can away changing using line to
using apply = f<ts...>; without harm. comes down rest of code doing. if type functions need have interface (::type or ::value) need conform them.
Comments
Post a Comment