Variadic alias template for nonvariant class template

While trying to write a simple example for currying metafunction classes, I wrote the following:

#include <type_traits>

struct first {
    template <typename T, typename U>
    using apply = T;
};

template <typename C, typename... Args>
struct curry {
    struct type {
        template <typename... OtherArgs>
        using apply = typename C::template apply<Args..., OtherArgs...>;
    };
};

int main() {
    static_assert(std::is_same<first::apply<int, char>, int>::value, ""); // OK

    using AlwaysInt = curry<first, int>::type;
    static_assert(std::is_same<AlwaysInt::apply<char>, int>::value, ""); // error
}

      

The second static_assert

will not compile like on gcc 5.1:

main.cpp:17:72: error: pack expansion argument for non-pack parameter 'U' of alias template 'template<class T, class U> using apply = T'
         using apply = typename C::template apply<Args..., OtherArgs...>;
                                                                        ^

      

and clang 3.6:

main.cpp:17:59: error: pack expansion used as argument for non-pack parameter of alias template
        using apply = typename C::template apply<Args..., OtherArgs...>;
                                                          ^~~~~~~~~~~~

      

Same error in both cases. However, if I pass the application in a curry

separate metaphor:

template <typename C, typename... Args>
struct eval {
    using type = typename C::template apply<Args...>;
};

template <typename C, typename... Args>
struct curry {
    struct type {
        template <typename... OtherArgs>
        using apply = typename eval<C, Args..., OtherArgs...>::type;
    };
};

      

Both compilers compile just fine . Is there something wrong with the original example or is it just a bug in both compilers?

+3


source to share





All Articles