C++Primer第5版の第16章テンプレートと汎用プログラミング
4165 ワード
第16章テンプレートと汎用プログラミング
テンプレートの定義
関数テンプレートテンプレート定義はキーワードtemplateで始まり、1つのテンプレートパラメータリスト(カンマで区切られた1つ以上のテンプレートパラメータのリスト)と<>で囲まれます. テンプレート定義では、テンプレートパラメータのリストを空にすることはできません. 実体化関数テンプレート:templateを呼び出すと、コンパイラは実体パラメータのタイプを使用してテンプレートパラメータTにバインドされたタイプを決定し、その後、コンパイラは推定されたテンプレートパラメータを使用して特定のバージョンの関数を実体化する. テンプレートタイプパラメータ:キーワードclassまたはtypenameを使用してテンプレートタイプパラメータを指定します(typenameがよく使用されます). 非タイプパラメータ:タイプではなく値を表し、キーワードclassまたはtypenameではなく特定のタイプ名で指定します. テンプレートがインスタンス化されると、非タイプパラメータは、ユーザが提供する値またはコンパイラによって推定された値に置き換えられ、これらの値は定数式でなければならない. 非タイプのテンプレートパラメータのテンプレート実パラメータは定数式である必要がある.
関数テンプレートはinlineまたはconstexprとして宣言することができ、inlineまたはconstexpr説明子はテンプレートパラメータリストの後に配置され、タイプを返す前に テンプレートコンパイル:テンプレートの特定のバージョンをインスタンス化すると、コンパイラはコードを生成します.関数テンプレートとクラステンプレートメンバー関数の定義は、通常、ヘッダファイルに配置されます.
クラステンプレートは、コンパイラがクラステンプレートのテンプレートパラメータタイプを推定することができず、パラメータタイプを明示的に提供する必要がある点で、クラスの青写真を生成するために使用される. クラステンプレートを使用する場合、テンプレートパラメータにバインドされたテンプレートの実パラメータを表示する追加情報を提供する必要があります.コンパイラは、これらのテンプレート実パラメータを使用して特定のクラスをインスタンス化します. クラステンプレートの各インスタンスは、独立したクラスを形成する.インスタンス化されたBlobは、他のBlobタイプに関連付けられておらず、他のBlobタイプのメンバーに特別なアクセス権を持つこともありません. クラステンプレートのコード別のテンプレートが使用されている場合、通常、インスタンスタイプの名前はテンプレートの実パラメータとして使用されず、逆にテンプレート自体のパラメータは使用されるテンプレートの実パラメータとして使用されます. クラス外でメンバー関数を定義する場合は、キーワードtemplateで開始し、クラステンプレートパラメータのリストに続く必要があります.また、メンバーがどのクラスに属しているかを説明する必要があります. のデフォルトでは、インスタンス化されたクラステンプレートのメンバーは、使用時にのみインスタンス化されます. クラステンプレートタイプを使用する場合は、テンプレートの実パラメータを指定する必要がありますが、クラステンプレート自体の役割ドメインでは、実パラメータではなくテンプレート名を直接使用できます. クラステンプレートのメンバーを外部に設定する場合は、クラス名に遭遇した場合にのみクラスの役割ドメインに入ることを示すことを覚えておく必要があります.
クラステンプレートと友元クラステンプレートに非テンプレート友元が含まれている場合、友元はすべてのテンプレートインスタンスにアクセスすることを許可される.友元自身がテンプレートである場合、クラスはすべての友元テンプレートインスタンスに権限を与えるか、特定のインスタンスにのみ権限を与えることができます. で友元宣言を行うには、まずテンプレート自体を先に宣言する必要があります. はtypedefを定義してインスタンス化されたクラスを参照したり、usingを使用してタイプ別名を宣言したりすることができます.
クラステンプレートのstaticメンバー各クラステンプレートのインスタンスには独自のstaticメンバーインスタンスがありますが、指定されたタイプについては、staticメンバーインスタンスが共有されます.クラステンプレートのstaticメンバーには定義が1つしかありません.
テンプレートの定義
関数テンプレート
template
int compare(const T &v1, const T &v2)
{
if (v1 < v2) return -1;
if (v2 < v1) return 1;
return 0;
}
template
calc(const T&, const U&);
template
int compare(const char (&p1)[N], const char (&p2)[M])
{
return strcmp(p1,p2);
}
compare("Hi", "Mom");
クラステンプレート
template
class Blob {
public:
//...
private:
std::shared_ptr<:vector>> data;
};
Blob ia;
//
std::shared_ptr> data; //T Blob
template
void Blob::check(size_type i, const string &msg) const
{
if (i >= data->size())
throw out_of_range(msg);
}
template
T& Blob::operator[](size_t i){
check(i, "subscript out of range"); //
return(*data)[i];
}
template
BlobPtr BlobPtr::operator++(int);
クラステンプレートと友元
// , Blob
template class BlobPtr;
template class Blob;
template
bool operator==(const Blob&, const Blob&);
template class Blob {
// Blob BlobPtr
friend class BlobPtr;
friend bool operator==
(const Blob&, const Blob&);
};
typedef Blob StrBlob; // Blob
template using twin = pair; //twin pair
twin authors; //authors pair
クラステンプレートのstaticメンバー