c++ - Examples on template metaprogramming over constexpr? -
is there examples out there template metaprogramming better use new constexpr? i've understood, both constexpr , template metaprogramming have similar purposes, yet template metaprogramming not obsolete. there has examples template metaprogramming preferred on constexpr. shared thoughts on highly appreciated, thanks!
constexpr
provides true support compile-time computing in form of true c++ functions instead of functional-like template-based constructions (metafunctions). partially answer yes constexpr beats tmp on compile time computing, @ least on syntax no fp initiated people used c++. note i'm ignoring concerns compiler performance etc.
on other hand, tmp still relevant, , way, type computing in c++. there new approaches improve horrible tmp syntax, boost.hana template variables. despite syntax, still functional metalanguage separated "normal" c++.
about type computing
from 2 common tasks may ask c++ compiler (besides compiling), playing type system generating new types on demand depending on requisites constexpr cannot achieve, because that's not constexpr supposed/designed do.
the fun part templates not supposed compile-time computing neither. metaprogramming. designed c++ feature generic programming. know story, middle 90s "whoaaa c++ templates turing complete!", expression templates , blitz++ later, alexandrescu , loki. , have <type_traits>
, serious proposal with full fledged metaprogramming library inside.
consider example (not mine, taken eric niebler "challenge"): write utility gives common type between set of types:
namespace m = ranges::meta; namespace ml = ranges::meta::lazy; template<typename t, typename u> using builtin_common_t = decltype(true? std::declval<t>() : std::declval<u>()); template<typename t, typename u> using lazy_builtin_common_t = m::defer<builtin_common_t, t, u>; template<typename...ts> struct common_type {}; template<typename ...ts> using common_type_t = m::eval<common_type<ts...>>; template<typename t> struct common_type<t> : std::decay<t> {}; template<typename t, typename u> struct common_type<t, u> : m::if_c< ( std::is_same<decay_t<t>, t>::value && std::is_same<decay_t<u>, u>::value ), ml::let<lazy_builtin_common_t<t, u>>, common_type<decay_t<t>, decay_t<u>>> {}; template<typename t, typename u, typename... vs> struct common_type<t, u, vs...> : ml::let<ml::fold<m::list<u, vs...>, t, m::quote<common_type_t>>> {};
as can see, problem types. constexpr not supposed do.
about challenge, eric asked both louis dionne (boost.hana author) , write common_type<ts...>
using our libraries. code above eric's implementation using meta library. sincerely, cannot beat louis's fold + maybe monad solution :)
Comments
Post a Comment