C++進級---day 01関数テンプレート
3814 ワード
前言
C++は関数テンプレート(function template)を提供する.関数テンプレートとは、実際には、関数タイプとパラメータタイプが具体的に指定されず、仮想タイプで表される汎用関数を確立することです.この汎用関数を関数テンプレートと呼ぶ.関数体が同じ関数はすべてこのテンプレートで代用することができて、複数の関数を定義する必要はなくて、テンプレートの中で一回定義するだけでいいです.関数を呼び出すと、テンプレート内の仮想タイプの代わりに実パラメータのタイプに基づいてシステムが置き換えられ、異なる関数の機能が実現されます.
なぜ関数テンプレートがあるのか
例:
上のコード:関数のタイプは違いますが、実現する機能は同じです.この場合、関数テンプレートを使用できます.
関数テンプレートは次のように適用されます.
出力20 10 b a
例示的な関数テンプレートのソートの例(整数およびchar型のソート)
出力:a f d a f d a f d d h g d j h 5 r e y h g n bの並べ替え後、y r n j h h g f f e d d d d d d d b a 5は任意のキーを押す続けてください.
一般関数とテンプレート関数の本質の違い
本質的な違いは、重荷に遭遇する場合です.//通常の関数の呼び出しで、暗黙的なタイプ変換ができます.//関数テンプレートの呼び出しは、タイプに厳密に一致し、自動タイプ変換は行われません.
関数テンプレートメカニズムの結論
コンパイラは関数テンプレートを任意のクラスを処理できるように処理する関数コンパイラではなく、関数テンプレートから具体的なタイプによって異なる関数コンパイラを生成すると、関数テンプレートを2回コンパイルし、宣言された場所でテンプレートコード自体をコンパイルする.呼び出した場所でパラメータ置換後のコードをコンパイルします.
C++は関数テンプレート(function template)を提供する.関数テンプレートとは、実際には、関数タイプとパラメータタイプが具体的に指定されず、仮想タイプで表される汎用関数を確立することです.この汎用関数を関数テンプレートと呼ぶ.関数体が同じ関数はすべてこのテンプレートで代用することができて、複数の関数を定義する必要はなくて、テンプレートの中で一回定義するだけでいいです.関数を呼び出すと、テンプレート内の仮想タイプの代わりに実パラメータのタイプに基づいてシステムが置き換えられ、異なる関数の機能が実現されます.
なぜ関数テンプレートがあるのか
例:
#include
using namespace std;
//
// , 。
void swapint(int &a, int &b)
{
int c = 0;
c = a;
a = b;
b = c;
}
void swapchar(char &a, char &b)
{
char c = 0;
c = a;
a = b;
b = c;
}
int main()
{
system("pause");
return 1;
}
上のコード:関数のタイプは違いますが、実現する機能は同じです.この場合、関数テンプレートを使用できます.
関数テンプレートは次のように適用されます.
#include
using namespace std;
//
// , 。
void swapint(int &a, int &b)
{
int c = 0;
c = a;
a = b;
b = c;
}
void swapchar(char &a, char &b)
{
char c = 0;
c = a;
a = b;
b = c;
}
//template C++ .
// T
template
//
void myswap(T &a, T &b)// 。
{
T t;
t = a;
a = b;
b = t;
}
// 。
int main()
{
{
int x = 10;
int y = 20;
myswap(x, y);// 。
printf("%d,%d", x, y);
}
{
char a = 'a';
char b = 'b';
myswap(a, b);// 。
printf("%c,%c", a, b);
}
system("pause");
return 1;
}
出力20 10 b a
例示的な関数テンプレートのソートの例(整数およびchar型のソート)
#include
using namespace std;
template //
int MySort(T *array, T2 size)
{
if (array == NULL)
{
return -1;
}
int j = 0;
T temp;
for (int i = 0; i < size; i++)
{
for (j = i + 1; j < size; j++)
{
if (array[i] < array[j])
{
temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
}
cout << endl;
return 1;
}
template
int MyPrint(T *array, T2 size)
{
for (T2 i = 0; i < size; i++)
{
cout << array[i] << " ";
}
return 1;
}
int main()
{
//int myarray[] = {1,2,5,76,8,2,3};
//int size = sizeof(myarray) / sizeof(*myarray);
。
MySort(myarray, size);
//cout << " " << endl;
//MyPrint(myarray, size);
//cout << " " << endl;
//MySort(myarray, size);
//MyPrint(myarray, size);
// char 。
{
char buf[] = "afdafdafdhgdjh5reyhgnb";
int len = strlen(buf);
MyPrint(buf, len);
MySort(buf, len);
cout << " " << endl;
MyPrint(buf, len);
}
system("pause");
return 1;
}
出力:a f d a f d a f d d h g d j h 5 r e y h g n bの並べ替え後、y r n j h h g f f e d d d d d d d b a 5は任意のキーを押す続けてください.
一般関数とテンプレート関数の本質の違い
本質的な違いは、重荷に遭遇する場合です.//通常の関数の呼び出しで、暗黙的なタイプ変換ができます.//関数テンプレートの呼び出しは、タイプに厳密に一致し、自動タイプ変換は行われません.
#include
using namespace std;
template
void myswap(T &a, T &b)
{
T c = 0;
c = a;
a = b;
b = c;
cout << "hello , call ." << endl;
}
void myswap(int a, char c)
{
cout << "a:" << a << "c:" << c << endl;
cout << " , ." << endl;
}
//
int main()
{
int a = 10;
char c = 'z';
myswap(a, c);// , 。
myswap(c, a);
myswap(a, a);// , , 。
system("pause");
return 1;
}
関数テンプレートメカニズムの結論
コンパイラは関数テンプレートを任意のクラスを処理できるように処理する関数コンパイラではなく、関数テンプレートから具体的なタイプによって異なる関数コンパイラを生成すると、関数テンプレートを2回コンパイルし、宣言された場所でテンプレートコード自体をコンパイルする.呼び出した場所でパラメータ置換後のコードをコンパイルします.