368
261

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

適当なC++テンプレート入門

Posted at

##はじめまして
Qiitaというものがあるそうじゃないですか、
適当にやったことをまとめようと思いまして、

##ところで

C++にはたくさんの型が存在します。
int float char std::string
などなど、自作の型も含めれば無数に存在します。

型というのは不自由なものでして、
型を決定してしまうことで、そのコード自体を不自由にしてしまう可能性があります。

例えばこんな関数

add.cpp
int Add(int a,int b){
    return a+b;
}

Add関数は見ての通りint型のみを受け取り、int型を返す関数になります。
もちろん引数にfloatなどの浮動小数点型を与えた場合はintにキャストされて小数点以下は切り捨てられるってわけですね。

まあ、C++のオーバーロードを使えば同名で多重定義することも可能です

add.cpp
int Add(int a,int b){
    return a+b;
}
float Add(float a,float b){
    return a+b;
}

これによって、intfloat限定でadd関数が使用可能になります。

先に上げたように、型は無数に存在するので
Add関数も無数に書かなければいけません。

ついでにいうと、このままではライブラリの開発者はユーザーがどんな型を使うのか予知する必要があります。

##関数テンプレート

プログラマは全員が予言者では無いので、
あらゆる型に対して適応できる万能のコードで書く必要があります

add.cpp
template<typename T>
T Add(T a,T b){
    return a+b;
}

とまあこんな感じで
template<class T>と記述することでTを任意の型として関数内で使用できます。

add.cpp
template<typename T,typename U>
T Add(T a,U b){
    return a+b;
}

二個以上の引数を取ることもできます。
この場合T=UでもT≠Uであってもこの関数が使用できます。

また、この関数の場合+演算子を使用できない型はコンパイル時にエラーが吐き出されます。

##テンプレートの特殊化

ある日僕は言われました

「俺はfloatが嫌いだ!そのAdd関数、floatの時だけ減算の処理をしてくれ!」

おまかせください。テンプレートには特定の型だけ違う処理をするテンプレートの特殊化の機能があります。

add.cpp
template <typename T>
T add(T a,T b){
	return a + b;
}

template <>
float add(float a,float b){
	return a - b;
}

こんな感じでfloatだけ別の処理にすることもできます。

##関数クラスメンバエイリアステンプレート

テンプレートには実は何種類かあります

  • 関数テンプレート
  • クラステンプレート
  • メンバテンプレート
  • エイリアステンプレート

####関数テンプレート

さっきのAdd関数とか

add.cpp
template <typename T>
T add(T a,T b){
	return a + b;
}

割と使う

####クラステンプレート

クラスと共に暮らす

myclass.cpp
template <typename T>
class myclass{
public:
    T value;
};

宣言の仕方はmyclass<int>のように宣言し、
テンプレート引数に指定した型を持つようになる。

####メンバテンプレート

正直、関数テンプレートとほとんど同じ

myclass2.cpp
class myclass2{
public:
    int nanika;

public:

    template<typename T>
    T Function(T a,T b);

};

メンバ関数にも関数テンプレートは使用できる。それだけ

####エイリアステンプレート

C++11からtypedefをusingで記述できるようになった

typedef TypographicError typo;
using typo = TypographicError;

これら2つは同様の意味を持つ。

そしてusingを使ったエイリアスにはテンプレートを使用できる

UsingTemplate.cpp
template<typename T,typename U>
T Add2(T a,U b);

template <typename T>
using Add1 = Add2<T,T>;

このように、型のエイリアスの作成、テンプレート引数の再編成などが行える。
でもC++11から

##まとめ
テンプレートを用いることで汎用的なプログラムコードを作成できる。
ここまで読んでくれた人はきっと既にテンプレートなしでは生きられない体になっているだろう。
テンプレートマスターになって再利用しやすいコードを書こう!

まあ、テンプレートの真の力はこんなものでは無いんだけどね。
それは又の機会に…

368
261
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
368
261

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?