更改模板,讓我們定義,change_templates
如下面的例子:對於給定的</p> <pre><code>template <typename...> class P; template <typename...> class Q; template <typename...> class R; template <typename...> class S; </code></pre> <p>包
change_templates<P<int, char, R<double, int>, bool>, P,Q, R,S>::type
是要
Q<int, char, S<double, int>, bool>
更普遍,
change_templates<P<int, Q<int, int>, char, P<double, P<char, char>, int>, bool>, P,Q, P,R, Q,S>::type
是要
Q<int, S<int, int>, char, R<double, P<char, char>, int>, bool>
(請注意,缺乏第三P,...
對意味着第三P是保持不變,雖然P,P
可以代替無論如何使用)。好消息是,我有它具有以下工作:
#include <iostream>
#include <type_traits>
template <template <typename...> class...> struct TP;
template <template <typename...> class, typename Templates, typename Checked = TP<>> struct find_template;
template <template <typename...> class P, template <typename...> class Q,
template <typename...> class... Rest, template <typename...> class... Checked>
struct find_template<P, TP<Q, Rest...>, TP<Checked...>> :
find_template<P, TP<Rest...>, TP<Checked..., Q>> {}; // Search the next template by default.
template <template <typename...> class P, template <typename...> class Q,
template <typename...> class... Rest, template <typename...> class... Checked>
struct find_template<P, TP<P, Q, Rest...>, TP<Checked...>> { // Q follows P, which means that P is to change to Q.
template <typename... Ts>
using type = Q<Ts...>;
using remaining_templates = TP<Checked..., Rest...>; // Every template except P,Q kept for later searches, since they have been used now.
};
template <template <typename...> class P, template <typename...> class... Checked>
struct find_template<P, TP<>, TP<Checked...>> { // P not found.
template <typename... Ts>
using type = P<Ts...>; // P not found, so simply don't change P.
using remaining_templates = TP<Checked...>;
};
template <typename T, template <typename...> class... Templates>
struct change_templates {
using type = T; // Base case. A non-pack type remains unchanged.
};
template <typename T, typename Templates> struct change_templates_impl;
template <typename T, template <typename...> class... Templates>
struct change_templates_impl<T, TP<Templates...>> :
change_templates<T, Templates...> {};
template <template <typename...> class P, typename... Ts, template <typename...> class... Templates>
struct change_templates<P<Ts...>, Templates...> { // A pack of types (possibly of other packs).
using F = find_template<P, TP<Templates...>>;
using Remaining = typename F::remaining_templates; // To be passed on for the next find_template call.
using type = typename F::template type<typename change_templates_impl<Ts, Remaining>::type...>; // Recursive call.
};
// Testing
template <typename...> class P; template <typename...> class Q;
template <typename...> class R; template <typename...> class S;
int main() {
static_assert (std::is_same<change_templates<P<int, char, double>, P, Q>::type, Q<int, char, double>>::value, "");
static_assert (std::is_same<
change_templates<P<int, char, R<double, int>, bool>, P,Q, R,S>::type,
Q<int, char, S<double, int>, bool>
>::value, "");
static_assert (std::is_same<
change_templates<P<int, Q<int, int>, char, P<double, P<char, char>, int>, bool>, P,Q, P,R, Q,S>::type, // The third P in the pack is unchanged because there is no pair for the third P.
Q<int, S<int, int>, char, R<double, P<char, char>, int>, bool>
>::value, "");
}
但現在我當然希望以下內容:
template <int...> class I; template <int...> class J;
int main() {
static_assert (std::is_same<
change_templates<P<int, char, I<4,5>, bool>, P,Q, I,J>::type,
Q<int, char, J<4,5>, bool>
>::value, "");
}
但我不知道如何去適應我上面的代碼來處理這個,因爲P,Q是類型的模板,而I,J是int的模板(或者更一般地說是任何整型)。有沒有辦法使不同類型的模板均勻化,以使上述內容按照預期工作(或者語法略有不同)?如果我們在同一包裝中同時包含int
包裝和std::size_t
等包裝?
我忍不住說「這段代碼看起來非常難以維護」 –
您可以使用'4'的std :: integral_constant'int作爲解決方法嗎? –
Jarod42