The following applies the conversion of type F to a list C types E... :
template <template <typename...> class F, typename P> struct apply_t; template < template <typename...> class F, template <typename...> class C, typename... E > struct apply_t <F, C <E...> > { typedef C <F <E>...> type; }; template <template <typename...> class F, typename P> using apply = typename apply_t<F, P>::type;
Now by entering this input:
template <typename T> using map1 = T*; template <typename T> using map2 = const T; template <typename T> using map3 = const T*;
I get the following output in gcc 4.8.1 using, for example, std::tuple :
apply <map1, tuple <int, char> > // -> tuple <int*, char*> (OK) apply <map2, tuple <int, char> > // -> tuple <int, char> // (tuple <const int, const char> expected) apply <map3, tuple <int, char> > // -> tuple <const int*, const char*> (OK)
I see output types using a utility template function that calls static_assert() .
I tried all kinds of combinations. Everything works, except for the map const T , in particular, when you specify an apply type as the input map. But it still works fine if I insert it into the definition of apply , i.e. typedef C <const E...> type .
On the other hand, everything works as expected in clang. I might be missing something, but it really looks like a gcc error.
Any ideas?