2015-06-02 11:54 GMT-03:00, Peter Dimov <lists@pdimov.com>:
[...]
I do agree that for branching one does need laziness. So if you want, f.ex.
template<class Def, template<class...> class F, class... T> using eval_or_default = /**/ // if is_evaluable<F, T...> returns F<T...> else returns Def
then I agree that you have to have a lazy if.
My basic question is "do you need laziness for something else apart from lazy if?"
The lazy version is not hard to recover, but I'm still wondering whether it's even necessary outside of if.
template<template<class...> class F, class... T> struct mp_defer { using type = F<T...>; };
mp_defer is a reasonable way of providing a lazy interface if it is only meant to be used in conjunction with your proposed eval_or_default. Apart from branching, laziness is also required for lambdas as presented by MPL, but if you are to argue that those are not necessary, than perhaps mp_defer might indeed be all you need. In any case I'd rather stick to the typename $<>::type vs $_t<> duality to mimic the standard library, but that of course is just a matter of personal taste. At any rate I think I agree with Louis that if one is restricted to such very simple cases, than perhaps <type_traits> is all one needs. That is, in my opinion any metaprogramming library should just go ahead and provide the more complex lambda facilities if it is to prove itself really useful for the end user. Bruno Dutra