的基本思想是一樣的@布萊恩的回答是:
- 元函數必須保持已使用(或相當於下一個可用值)的值,並將所得類型的軌道。
- 由於列表中每種類型的處理都依賴於以前的類型,所以簡單的包擴展是不可行的,您需要使用遞歸來處理它。
最小的區別是我沒有使用單獨的計數器類型,而且我做了前序遍歷而不是後序遍歷。我也以不同的方式處理了連接。
// This is the base case, used only when T is not a mytype.
// N is the next index available to be used.
// The third argument is used to hold types that has been processed
// during the recursion.
template<class T, int N = 0, class = mytype<-1>> struct assign_IDs {
using type = T;
static constexpr int next_index = N;
};
// When we are starting to process a mytype.
template<class T, class...Ts, int N, int M1, int M2>
struct assign_IDs<mytype<M1, T, Ts...>, N, mytype<M2>> {
// Process the first type in the list.
// The first available index is N+1 since we are using N.
using T_assigned = assign_IDs<T, N + 1>;
// recursively process the next type
using next = assign_IDs<mytype<N, Ts...>, T_assigned::next_index, mytype<N, typename T_assigned::type>>;
using type = typename next::type;
static constexpr int next_index = next::next_index;
};
// When we are in the middle of processing a mytype. The difference
// is that we won't consume an index any more.
template<class T, class...Ts, class... Vs, int N, int M1, int M2>
struct assign_IDs<mytype<M1, T, Ts...>, N, mytype<M2, Vs...>> {
// now the handling of T can start at N.
using T_assigned = assign_IDs<T, N>;
using next = assign_IDs<mytype<M1, Ts...>, T_assigned::next_index, mytype<M2, Vs..., typename T_assigned::type>>;
using type = typename next::type;
static constexpr int next_index = next::next_index;
};
// end of recursion: all types have been processed.
// The resulting type is just the third template argument.
template<class... Vs, int N, int M1, int M2>
struct assign_IDs<mytype<M1>, N, mytype<M2, Vs...>> {
using type = mytype<M2, Vs...>;
static constexpr int next_index = N;
};
Demo。
A postorder traversal實際上是容易實現,因爲它需要一個較少的偏特:
// same as before
template<class T, int N = 0, class = mytype<-1>> struct assign_IDs {
using type = T;
static constexpr int next_index = N;
};
// can merge case #2 and #3 because now the handling is the same
// as the index isn't consumed until the end of the recursion
template<class T, class...Ts, class... Vs, int N, int M1, int M2>
struct assign_IDs<mytype<M1, T, Ts...>, N, mytype<M2, Vs...>> {
using T_assigned = assign_IDs<T, N>;
using next = assign_IDs<mytype<M1, Ts...>, T_assigned::next_index, mytype<M2, Vs..., typename T_assigned::type>>;
using type = typename next::type;
static constexpr int next_index = next::next_index;
};
// end of recursion, consume an index for the current mytype that we are processing
template<class... Vs, int N, int M1, int M2>
struct assign_IDs<mytype<M1>, N, mytype<M2, Vs...>> {
using type = mytype<N, Vs...>;
static constexpr int next_index = N + 1;
};
OTOH,我喜歡有遞增的順序號碼顯示類型時。
它可以'mytype <0,mytype <...>,mytype <...>>'?或者是最內層的'mytype'是唯一一個具有多種類型的? – 2015-03-30 22:42:03
http://coliru.stacked-crooked.com/a/1404d3d38fc41fb6更簡單的情況。允許同一級別的多個「mytype」會更棘手。 – 2015-03-30 22:49:48
@ T.C。它可以是。我將編輯顯示的問題。 – refi64 2015-03-30 22:52:20