C++ のお勉強 テンプレート編
C++ のお勉強三日目。前回の「C++ のお勉強 クラス編」の続き。
三日坊主もイイトコロなので,このテンプレート編が最後のお勉強になる。
C++ は難しいもんだと思ってたけど,今回までで,もう C++ の概要を掴むことが出来た…気がする。C をやっとけば C++ の習得は楽だってウワサは本当らしいね。
あと,本来の目的は L4 のコードを読むことだから,入出力に関しては詳しく調べなかった。
テンプレート関数
- 例えば,二つの引数を取り大きいほうの数字を返すmax()という関数を作ってみる
- 関数のオーバーライドを使う:
int max(int a, int b) { return (a>b) ? a : b ; } double max(double a, double b) { return (a>b) ? a : b ; }
-
-
- これでは,各引数の型毎に関数を定義しなければならない
- そこで,テンプレート関数を使う
-
- 関数の先頭に次のような宣言を付加することで,どんな型でも扱えるテンプレート関数を作成できる
template <テンプレート引数宣言>
-
- テンプレート引数は関数宣言や定義の中で型名として使用でき,この型が任意の型に変換される
- どんな型でも扱え,さらに型安全性が保障される
- テンプレート引数は関数宣言や定義の中で型名として使用でき,この型が任意の型に変換される
#include <stdio.h> template<class T> T max(T a, T b) { return (a>b) ? a : b ; } int main() { int a=1, b=2; double x=10.0, y= 20.0; printf("max %d \n", max(a, b)); // => max 2 printf("max %.1f \n", max(x, y)); // => max 20.0 //これはエラーになる //printf("max %d \n", max(a, x)); //ただし,次のように型を定義できる printf("max %d \n", max<int>(a, x)); // => max 10 return 0; }
テンプレートクラス
- テンプレートはクラスでも同様に使える
- スタックを作るときに使うと便利そう
#include <stdio.h> template<class X> class Stack { X buf[128]; int index; public: void push(X var) { buf[index++] = var; } X pop() { return buf[--index]; } Stack() { index = 0; } }; int main() { Stack <int> stack1; stack1.push(10); stack1.push(20); printf("%d \n", stack1.pop()); // => 20 printf("%d \n", stack1.pop()); // => 10 Stack <const char *> stack2; stack2.push("hoge"); stack2.push("hage"); printf("%s \n", stack2.pop()); // => hage printf("%s \n", stack2.pop()); // => hoge return 0; }
付録 入出力ストリーム
- C++ の入出力は,ストリームと呼ばれる流れとして抽象化されている
- 入出力ストリームは,階層的に構成されたクラスとして定義され,iostream というヘッダファイルに含まれている
- 例えば,文字を表示するには,次のようにして標準出力にデータを流してやる
std::cout << "hello, world";
-
- 出力するデータの形は気にしなくていい
#include <iostream> int main() { std::cout << "hoge"; // => hoge std::cout << "10"; // => 10 std::cout << "0.1"; // => 0.1 return 0; }
-
-
- つまり,<<はオーバーロード可能ってこと
-
- 入出力ストリームは奥が深そうだからこれ以上詮索しない:-)