簡體   English   中英

模板模板參數的專業化

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM