[英]Specialization of template template parameters
這是對早期問題的續集問題(關於不同的主題)。 下面的代碼包含了Dehstil關於使用專業化的建議。
具有模板模板參數的函數應該如何專門化?
下面的代碼(兩個專業化行不編譯)使問題具體化。
#include <cassert>
template<typename S> struct PA1 {};
template<typename S> struct PA2 {};
template<typename S> struct PB {};
template<typename S> struct PC {};
template<typename S> struct A1 { typedef PA1<S> P; };
template<typename S> struct A2 { typedef PA2<S> P; };
template<typename S> struct B { typedef PB <S> P; };
template<typename S> struct C { typedef PC <S> P; };
template<typename S, template<typename> class T> char fn(typename T<S>::P);
template<typename S, template<typename> class T> char fn(typename T<S>::P)
{
return 'a';
}
template<typename S> char fn<B<S> >(B<S>::P) { return 'b'; }
template<typename S> char fn<C<S> >(C<S>::P) { return 'c'; }
int main()
{
PA1<int> pa1;
PA2<int> pa2;
PB<int> pb;
PC<int> pc;
assert( (fn<int, A1>(pa1)) == 'a' );
assert( (fn<int, A2>(pa2)) == 'a' );
assert( (fn<int, B>(pb)) == 'b' );
assert( (fn<int, C>(pc)) == 'c' );
}
重要的是四個函數調用fn <...,...>()在調用時具有相同的簽名,因為它們本身將駐留在適用於四個類A1 / A2 / B / C的模板類中。
C ++標准不允許部分專業化功能模板!
重載您的功能而不是專門化它們。
閱讀有關為何不專業化功能模板的說明? 作者:Herb Sutter
然后閱讀為什么超載而不是專門化: Herb Sutter的 模板專業化和重載
編寫一個類模板call
並將它們專門化為:
template<class S, template<typename> class T>
struct call
{
static char fn(typename T<S>::P &p)
{
return ::fn<S,T>(p);
}
};
template<class S>
struct call<S,B>
{
static char fn(typename B<S>::P &p)
{
return ::fn<S>(p);
}
};
template<class S>
struct call<S,C>
{
static char fn(typename C<S>::P &p)
{
return ::fn<S>(p);
}
};
然后,您可以使用此類模板統一調用所有函數:
assert( (call<int, A1>::fn(pa1)) == 'a' );
assert( (call<int, A2>::fn(pa2)) == 'a' );
assert( (call<int, B>::fn(pb)) == 'b' );
assert( (call<int, C>::fn(pc)) == 'c' );
請參閱在線演示: http : //www.ideone.com/TISIT
另請注意ideone.com上完整解決方案中的重載功能模板(上面的鏈接)
功能只能完全專業化。 使用函數重載:
template<typename S> char fn(typename B<S>::P) { return 'b'; }
template<typename S> char fn(typename C<S>::P) { return 'c'; }
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.