Bruno Dutra wrote:
What you mean? std::decay<>::type is the lazy backend.
Eh, no, it's just an implementation detail. Change your template<> struct test_c<void>{using type = void;}; to template<> struct test_c<int>{using type = int;}; and then look at the following decay<> of mine, which I'm sure you'll agree really has no "lazy backend". template<class T> T make(); template<class T> T decay_impl(T); template<class T> using decay = decltype(decay_impl(make<T&&>())); template<class T> using test2 = test<decay<T>>; static_assert(is_evaluable<test2, int const volatile>::value, ""); static_assert(!is_evaluable<test2, int()>::value, ""); static_assert(!is_evaluable<test2, void, int>::value, ""); is_evaluable still works as expected. It even works on decay<> directly: static_assert(is_evaluable<decay, int const volatile>::value, ""); static_assert(is_evaluable<decay, int()>::value, ""); static_assert(!is_evaluable<decay, int, float>::value, ""); static_assert(!is_evaluable<decay, void>::value, "");