変数を交換する方法
1. マクロコードブロックを定義する
- 利点: コードの再利用性が高く、あらゆる型に適応できる
- 欠点: コンパイラはマクロの位置を知ることができず、型チェックができない
2. 関数を定義する
- 利点: 実際の関数呼び出しであり、コンパイラが型をチェックする
- 欠点: 型ごとに関数を再定義する必要があり、コードの再利用性が低い
<strong>#include <iostream>
using namespace std;
#define SWAP(t, a, b) \
do \
{ \
t c = a; \
a = b; \
b = c; \
}while(0)
void swap(int& a, int& b)
{
int i = a;
a = b;
b = i;
}
/*
void swap(double& a, double& b)
{
int i = a;
a = b;
b = i;
}
*/
int main()
{
int a = 1;
int b = 2;
swap(a, b);
cout << "swap(a, b):" << a << "," << b << endl;// 输2,1
SWAP(int, a, b);
cout << "SWAP(int, a, b):" << a << "," << b << endl;//输出1, 2
return 0;
}</strong>
ジェネリックプログラミングと関数テンプレート
1. ジェネリックプログラミングの概念: 具体的な型を考慮しないプログラミング方式
2. C++におけるジェネリックプログラミング: 関数テンプレート
- (1): 異なる型で呼び出せる特殊な関数
- (2): 普通の関数に似ているが、型がパラメータ化されている
3. 関数テンプレートの構文規則
- (1): templateキーワードはジェネリックプログラミングの開始を宣言する
- (2): typenameキーワードは汎用的な型を宣言する
4. 関数テンプレートの使用
- (1): 自動推論による呼び出し
- (2): 明示的に指定された型での呼び出し
<strong>#include <iostream>
#include <string>
using namespace std;
template < typename T >
void Swap(T& a, T& b)
{
T c = a;
a = b;
b = c;
}
template < typename T >
void Sort(T a[], int len)
{
for(int i=0; i<len; i++)
{
for(int j=i; j<len; j++)
{
if( a[i] > a[j] )
{
Swap(a[i], a[j]);
}
}
}
}
template < typename T >
void Println(T a[], int len)
{
for(int i=0; i<len; i++)
{
cout << a[i] << ", ";
}
cout << endl;
}
int main()
{
int a[5] = {5, 3, 2, 4, 1};
Println(a, 5);
Sort(a, 5);
Println(a, 5);
string s[5] = {"Java", "C++", "Pascal", "Ruby", "Basic"};
Println(s, 5);
Sort(s, 5);
Println(s, 5);
return 0;
}</strong>
まとめ
(1): 関数テンプレートはC++におけるジェネリックプログラミングの一つの方法である(他にもクラステンプレートがある)
(2): 関数テンプレートは実引数によってパラメータの型を推論することができる
(3): 関数テンプレートは明示的にパラメータの型を指定することも可能である
(4): 関数テンプレートはC++において重要なコードの再利用手段である