![](/img/trans.png)
[英]How to check if a template parameter in a function matches a specialization of a given type alias
[英]How to replace a template parameter in a given type?
假設名為B
的模板參數的類型為C<D>
(在實例化時),那么如何從B
構造C<A>
?
這是我的代碼的最小化摘錄:
template<typename A>
class foo {
template<typename B> // B is guaranteed to always be of the form C<D>
// How to write a function here with return type C<A>?
}
template<typename, typename>
struct meta {};
template<typename A, template<typename> typename C, typename B>
struct meta<A, C<B>> {
using type = C<A>;
};
meta<A, C<B>>::type
將為C<A>
如果您想在基本情況下處理默認參數
template<typename...>
struct meta {};
template<typename A, template<typename...> typename C, typename B, typename ... Ts>
struct meta<A, C<B, Ts...>> {
using type = C<A, Ts...>;
};
首先,我們編寫一些機制來替換模板類型實例中的類型:
template<class In, class Replace>
struct replace_first_type;
template<template<class...>class Z, class T0, class...Ts, class Replace>
struct replace_first_type<Z<T0, Ts...>, Replace> {
using type=Z<Replace, Ts...>;
};
template<class In, class Replace>
using replace_first = typename replace_first_type<In,Replace>::type;
replace_first< Z, X >
接受Z
,pattern將其與任何template<class...>
匹配,獲取第一個參數,並將其替換為X
這不適用於std::array<int, 7>
因為7
不是類型,但適用於std::vector<int>
; vector
實際上是帶有默認參數的<T, A>
。 template<class...>
模式與采用0個或更多類的模板匹配。
然后,我們將其應用:
template<typename A>
class foo {
template<typename B>
using result = replace_first<B, A>;
};
現在foo<int>::template result< std::vector<double> >
是std::vector<int, std::alloctor<double>>
。 當然,這是一個非常愚蠢的類型。
如果具有功能:
template<class B>
result<B> do_something() {
return {};
}
實際上返回該類型的值。
我們可以通過遞歸替換我們替換的類型來解決上述std::allocator<double>
的問題...
template<class X, class Src, class Dest>
struct subst_type {
using type=X;
};
template<class X, class Src, class Dest>
using subst_t = typename subst_type<X, Src, Dest>::type;
template<template<class...>class Z, class...Ts, class Src, class Dest>
struct subst_type<Z<Ts...>, Src, Dest> {
using type=Z<subst_t<Ts, Src, Dest>...>;
};
template<class Src, class Dest>
struct subst_type<Src, Src, Dest> {
using type=Dest;
};
並申請先替換:
template<class In, class Replace>
struct replace_first_type;
template<template<class...>class Z, class T0, class...Ts, class Replace>
struct replace_first_type<Z<T0, Ts...>, Replace> {
using type=Z<Replace, subst_t<Ts, T0, Replace>...>;
};
現在當我們foo<int>::result<std::vector<double>>
我們得到std::vector<int, std::allocator<int>>
而不是std::vector<int, std::allocator<double>>
(這是無用的類型)。
現場例子 。
在模板的其余自變量中用B
遞歸替換A
可能會導致一些嚴重錯誤,但是如前所述,如果不這樣做,我們對於通用模板肯定會感到可怕。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.