Q:

Template pack of pack

For example, we have types containers
Container1< Pack1...> , Container2< Pack2...> etc.
And if we wrote:
template <template <typename... Pack>
          typename ...Containers,

          typename... Pack
          >
auto Concatinate(Container<Pack...>...)
    -> Container<Pack...>;

This would not work with containers of different types of template arguments.That is,
The function cannot be instantiated with these containers:
Container1<Pack1...>, Container2<Pack2...> etc.
If Pack1... != Pack2... etc.
But I want one small function, like this one, that can combine the types of the template arguments into a container.
Is there 
typename ... ... PackOfPack

?
(Types container means structure kind of tuple)

A:

There is no ... ... in C++ that does what you want.
You'll have to write more complex metaprogramming that does it pair wise.
template<class T0, class...Ts>
struct pack_concat;
template<class T0>
struct pack_concat<T0> { using type=T0; };

template<template<class...>class C0, template<class...>class C1, class...T0s, class...T1s, class Ts...>
struct pack_concat< C0<T0s...>, C1<T1s...>, Ts... >:
  pack_concat< C0<T0s..., T1s...>, Ts... >
{};

template<class T0, class...Ts>
using pack_concat_t = typename pack_concat<T0, Ts...>::type;

So your code becomes:
template<
  template<class...>class Container,
  class... Pack,
  class... Rest
>
auto Concatinate(Container<Pack...> c0, Rest...)
-> pack_concat_t< Container<Pack...>, Rest... >;

(Note that this is O(n^2) total instantiation "name" length; a O(n lg n) solution is possible, but overly complex.  And this is me talking.)

A:

What about using std::tuple_cat()?
I mean... what about something as follows ?
template <template <typename ...> class Cnt, typename ... Ts>
std::tuple<Ts...> to_tuple (Cnt<Ts...>);

template <typename ... Ts>
auto concatinate (Ts ... ts)
   -> decltype ( std::tuple_cat(to_tuple(ts)...) );

The preceding concatinate() return a std::tuple with all types contained in all Ts... type container (given that all Ts... are types container) but if you want another return-container, the construction of a from_tuple() function (so -> decltype ( from_tuple(std::tuple_cat(to_tuple(ts)...)) );) is trivial
The following is a full compiling example
#include <tuple>
#include <iostream>
#include <functional>

template <template <typename ...> class Cnt, typename ... Ts>
std::tuple<Ts...> to_tuple (Cnt<Ts...>);

template <typename ... Ts>
auto concatinate (Ts ... ts)
   -> decltype ( std::tuple_cat(to_tuple(ts)...) );

template <typename...> struct cnt1 { };
template <typename...> struct cnt2 { };
template <typename...> struct cnt3 { };

int main()
 {
   using pack1 = cnt1<int, long, long long>;
   using pack2 = cnt2<long, long long, long>;
   using pack3 = cnt3<long long, long, int>;

   using expected_tuple = std::tuple<int, long, long long,
                                     long, long long, long,
                                     long long, long, int>;

   using final_tuple = decltype(concatinate(std::declval<pack1>(),
                                            std::declval<pack2>(),
                                            std::declval<pack3>()));

   static_assert( std::is_same_v<expected_tuple, final_tuple>, "!" );

 }

