C++Template基礎編(三):パラメータ魔法
6457 ワード
Template基礎編-パラメータ魔法
Templateが代表する汎用プログラミングはC++言語の重要な構成部分であり、私はいくつかのblogを通じてこの半年以来の学習を系統的に総括し、本文は基礎編の第3部分である. Template基礎編-パラメータ魔法 デフォルトパラメータ テンプレートのテンプレートパラメータ 非タイプパラメータ
テンプレートのパラメータとしてタイプを使用する以外に、テンプレートパラメータにはより多くの使い方があります.以下で詳しく説明します.
デフォルトの実パラメータ
テンプレートにデフォルトの実パラメータを指定することで、ユーザーに適切なデフォルト設定を推奨し、一部(またはまったく指定しない)の実パラメータのみを指定した場合にテンプレートを使用することができます.
注:テンプレートのデフォルトの実参加関数のデフォルトの実パラメータは、右から左に定義する必要があります.
C++98では、クラステンプレートにデフォルトの実パラメータしか指定できません.
C++11では、関数テンプレートにデフォルトの実パラメータを指定することもできます.
テンプレートのテンプレートパラメータ
組み込みタイプ(int float boolなど)とカスタムタイプ(class struct)がテンプレートの実パラメータとして使用できるほか、C++は1つのテンプレートを別のテンプレートの実パラメータとして使用することを許可し、これによりテンプレートのユーザーがテンプレートの動作を深くカスタマイズすることができる.たとえば、別のSTLコンテナを使用するテンプレート格納データを指定します.
テンプレートのテンプレートパラメータを宣言する場合は、templateキーとclassキーを使用し、別のテンプレートの完全な宣言を使用する必要があります.
非タイプパラメータ
C++テンプレートは非タイプパラメータもサポートしており、テンプレート定義で特定のタイプを使用して指定できます.非タイプパラメータは、整形、またはポインタまたは左値参照です.
注:非タイプパラメータを含む関数テンプレートでは、整形推定の結果は定数式でなければなりません.ポインタと参照推定の結果は、静的生存サイクルを持つオブジェクト(staticまたはグローバル)またはnullptrまたは0を指す必要があります.
Templateが代表する汎用プログラミングはC++言語の重要な構成部分であり、私はいくつかのblogを通じてこの半年以来の学習を系統的に総括し、本文は基礎編の第3部分である.
テンプレートのパラメータとしてタイプを使用する以外に、テンプレートパラメータにはより多くの使い方があります.以下で詳しく説明します.
デフォルトの実パラメータ
テンプレートにデフォルトの実パラメータを指定することで、ユーザーに適切なデフォルト設定を推奨し、一部(またはまったく指定しない)の実パラメータのみを指定した場合にテンプレートを使用することができます.
注:テンプレートのデフォルトの実参加関数のデフォルトの実パラメータは、右から左に定義する必要があります.
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を指す必要があります.