C++Template基礎編(三):パラメータ魔法

6457 ワード

Template基礎編-パラメータ魔法
Templateが代表する汎用プログラミングはC++言語の重要な構成部分であり、私はいくつかのblogを通じてこの半年以来の学習を系統的に総括し、本文は基礎編の第3部分である.
  • Template基礎編-パラメータ魔法
  • デフォルトパラメータ
  • テンプレートのテンプレートパラメータ
  • 非タイプパラメータ

  • テンプレートのパラメータとしてタイプを使用する以外に、テンプレートパラメータにはより多くの使い方があります.以下で詳しく説明します.
    デフォルトの実パラメータ
    テンプレートにデフォルトの実パラメータを指定することで、ユーザーに適切なデフォルト設定を推奨し、一部(またはまったく指定しない)の実パラメータのみを指定した場合にテンプレートを使用することができます.
    注:テンプレートのデフォルトの実参加関数のデフォルトの実パラメータは、右から左に定義する必要があります.
    C++98では、クラステンプレートにデフォルトの実パラメータしか指定できません.
    template<typename T = int, typename U> //error,       
    struct Wrapper1 {
          T t;
    };
    
    template<typename T, typename U = int> //ok
    struct Wrapper2 {
        T t;
    };
    Wrapper2<double> w;
    
    template<typename T = int>
    struct Wrapper3 {
        T t;
    };
    Wrapper3<> w; //w    Wrapper,    <>    

    C++11では、関数テンプレートにデフォルトの実パラメータを指定することもできます.
    template<typename T, typename F = std::less> //  F     std::less
    int compare(const T& left, const T& right, F f = F()) { //    ,std::less   functor
        if (f(left, right)) {
            return -1;
        }
        if (f(right, left)) {
            return 1;
        }
        return 0;
    }
    compare(1, 2); //        ,     std::less

    テンプレートのテンプレートパラメータ
    組み込みタイプ(int float boolなど)とカスタムタイプ(class struct)がテンプレートの実パラメータとして使用できるほか、C++は1つのテンプレートを別のテンプレートの実パラメータとして使用することを許可し、これによりテンプレートのユーザーがテンプレートの動作を深くカスタマイズすることができる.たとえば、別のSTLコンテナを使用するテンプレート格納データを指定します.
    テンプレートのテンプレートパラメータを宣言する場合は、templateキーとclassキーを使用し、別のテンプレートの完全な宣言を使用する必要があります.
    template<typename T, 
             template<typename ELEM> typename CONT> //error,    class   
    class ContainerWrapper {
    public:
        CONT elems;
    };
    
    template<typename T, 
             template<typename ELEM> class CONT> //ok
    class ContainerWrapper {
    public:
        CONT elems;
    };
    
    ContainerWrapper<int, std::deque> cw; //error,std::deque   
    //std::deque   ELEM           Alloc  
    
    template<typename T, 
             template<typename ELEM, typename ALLOC = std::allocator> 
             class CONT = std::deque> //  STL       ,   deque,  template class     
    class ContainerWrapper {
    public:
        CONT elems;
    };
    
    ContainerWrapper<int> cw_default; //  deque  
    ContainerWrapper<double, std::vector> cw_customized; //         vector

    非タイプパラメータ
    C++テンプレートは非タイプパラメータもサポートしており、テンプレート定義で特定のタイプを使用して指定できます.非タイプパラメータは、整形、またはポインタまたは左値参照です.
    template<unsigned N, unsigned M> //  unsigned       
    int compare(const char (&left) [N], const char (&right) [M]) {
        return compare(left, right);
    }
    
    compare("hi", "hello"); //   N=3,M=6
    
    template<typename T, int N>
    class WrapperWithNum {
    public:
        T t;
    };
    
    WrapperWithNum<int, 1> wwn1;
    WrapperWithNum<int, 2> wwn2; //  :         T  int,    N  ,        

    注:非タイプパラメータを含む関数テンプレートでは、整形推定の結果は定数式でなければなりません.ポインタと参照推定の結果は、静的生存サイクルを持つオブジェクト(staticまたはグローバル)またはnullptrまたは0を指す必要があります.