関数テンプレートを設定することにより自作関数の戻り値が格納される型をmain関数内で自由に設定することができます

ソーラー「



     関数名が同じで引数の数が同じ数の💖💖💖💖💖💖💖💖💖自作関数の定義を複数設定すると


自作関数の実行時にビルドエラーが表示されることがあります


そのことを示すために


以下のように


同じfunctionという名前の自作関数の定義を


2つ設定して


プログラムを実行してみたいと思います


その2つの定義を以下のように設定してみます

👇

int function(int a, int b) {


cout << a + b << "\n";


int c=a+b;


return c;

}



float function(float a, float b) {


cout << a + b << "\n";


float c=a+b;


return c;

}


👆

これら2つの自作関数functionの定義は


戻り値を格納する型が


int

float


と異なっていて


引数の型も


int

float

異なっていますが


引数の数は2個と等しくなっています


それでは


これら2つの自作関数functionの定義が用いられたプログラムを


実行してみたいと思います」


solarplexuss「さすがにそれは無理でしょう」


そのプログラムはこちらです

👇


#include <iostream>


using namespace std;


int function(int a, int b) {


cout << a + b << "\n";


int c=a+b;


return c;

}



float function(float a, float b) {


cout << a + b << "\n";


float c=a+b;


return c;

}



int main() {


function(1.11,2.22);


return 0;


}


ビルド実行結果



エラー (アクティブ) E0308 オーバーロードされた関数 "function" の複数のインスタンスが引数リストと一致します:

エラー C2668 'function': オーバーロード関数の呼び出しを解決することができません。(新機能 ; ヘルプを参照)



ソーラー「ビルド実行エラーが表示されました


このように


引数の数が同じ2つとなっている状態で


同じ名前の自作関数functionの定義を複数設定する


つまり


自作関数functionのオーバーロードを実行することはできません


ということは


int function(int a, int b) {


cout << a + b << "\n";


int c=a+b;


return c;

}



float function(float a, float b) {


cout << a + b << "\n";


float c=a+b;


return c;

}



のどちらかしか


自作関数functionの定義が設定できないことになります



まず


int function(int a, int b) {


cout << a + b << "\n";


int c=a+b;


return c;

}


だけを設定した場合のプログラムはこちらです

👇

#include <iostream>


using namespace std;


int function(int a, int b) {


cout << a + b << "\n";


int c=a+b;


return c;

}


int main() {


int i = function(1.11, 2.22);


cout << i << "\n";


return 0;


}


プログラムの実行結果


3

3


ソーラー「ちゃんとビルド実行できていますね


function(1.11, 2.22)の戻り値として


3


が返されています




次に自作関数functionの定義として


float function(float a, float b) {

cout << a + b << "\n";


float c=a+b;

return c;

}


だけを設定した場合のプログラムはこちらです」

👇


#include <iostream>


using namespace std;


float function(float a, float b) {

cout << a + b << "\n";


float c = a + b;

return c;

}


int main() {


float j = function(1.11, 2.22);


cout << j << "\n";


return 0;


}


プログラムの実行結果


3.33

3.33


ソーラー「こちらもちゃんとビルド実行できました


function(1.11, 2.22)の戻り値として


3.33


が返されています



どちらかの自作関数functionの定義を用いることになるので


戻り値に


3

3.33


が返されて


プログラムの実行結果に


整数値

3

3


実数値

3.33

3.33


のどちらかが表示されることになります



もちろん


自作関数functionの定義が設定されているので


あとから


main関数内で


function(1.11, 2.22)が実行されたとき


function(1.11, 2.22)に返される


戻り値が格納される型を変更することはできません



int function(int a, int b) {

cout << a + b << "\n";

int c=a+b;


return c;

}


自作関数functionの定義が設定されていたなら


function(1.11, 2.22)が実行されたとき


function(1.11, 2.22)に返される


戻り値を格納する型は


          intのままであり



float function(float a, float b) {

cout << a + b << "\n";


float c = a + b;

return c;

}


自作関数functionの定義が設定されていたなら


function(1.11, 2.22)が実行されたとき


function(1.11, 2.22)に返される


戻り値を格納する型は


          floatのままですね



マックス「それはそうだろう


普通のことなんじゃないか?」


ソーラー「そうですね


実は自作関数function(1.11, 2.22)の実行されたとき


           戻り値が



          int型に格納されるか?

          float型に格納されるか?


main関数内で決めることができるよう


自作関数functionの定義を設定することができます



そのために


関数テンプレートというものを用います」



マックス「異世界転生ものテンプレートだとぉ!!!???」


ソーラー「ちがいますっっ


ところで


2つの自作関数functionの定義


👇

int function(int a, int b) {


cout << a + b << "\n";

int c=a+b;


return c;

}



float function(float a, float b) {


cout << a + b << "\n";


float c = a + b;


return c;

}

をご覧ください


この2つは


構造がとても似ていますね」


マックス「確かに


そうだな


int

float

の部分以外は全く一緒だな」


ソーラー「


ところで


自作関数functionの定義を


template<class T>


T function(T a, T b) {

cout << a + b << "\n";


T c=a+b;

return c;

}


と記述しておくこともできます」


マックス「にゃんだ?」


ソーラー「

この

👇

template<class T>


T function(T a, T b) {

cout << a + b << "\n";

T c = a + b;


return c;

}

👆

を関数テンプレートといいます


テンプレートとは"ひながた"という意味であり


関数テンプレートとは関数の"ひながた"という意味です



このように


自作関数functionの定義を記述しておけば



main関数内で


自作関数functionが実行されたとき


Tにintが代入されるか


Tにfloatが代入されるか



自由にきめることができます」


マックス「げげっ


そんなことができるのか?」


ソーラー「そのことを示すプログラムはこちらです


👇

#include <iostream>


using namespace std;


template<class T>


T function(T a, T b) {


cout << a + b << "\n";


T c = a + b;


return c;

}


int main() {


int i=function(1.11, 2.22);


float j = function(1.11, 2.22);


cout << i << "\n";

cout << j << "\n";


return 0;


}


ビルド実行結果


3.33

3.33

3

3.33


solarplexuss「!!⁉」


ソーラー「


int i=function(1.11, 2.22);



御注目下さい


function(1.11, 2.22);


が実行されたときの戻り値は


int型💖💖💖の変数iに格納されることになります




function(1.11, 2.22);


が実行されるとき


T function(T a, T b) {


cout << a + b << "\n";


T c = a + b;


return c;

}



Tにintが代入された


int function(int a, int b) {


cout << a + b << "\n";


int c = a + b;


return c;

}


さらに


aに1.11

bに2.22

代入された状態で


int function(int a, int b) {


cout << a + b << "\n";


int c = a + b;


return c;

}

が実行されることになります


となると


int aに1.11

int bに2.22


が代入されることになるので


数値データの型変換が起こり


aには1

bには2


代入されることになり


cout << a + b << "\n";

の実行結果は


3


が表示されるはずですが


3.33


が表示されます


マックス「???なぁ~んでだ?」


ソーラー「そこが


不思議なところで


a+b


が実行されても


a+b



3.33


をあらわすこととなります


つまり


T function(T a, T b) {

cout << a + b << "\n";

T c = a + b;


return c;

}



Tにintが代入された


int function(int a, int b) {

cout << a + b << "\n";

int c = a + b;


return c;

}

が実行されるといっても


引数部分の

int a

int b



intは型としての役割を果たしていないというわけです


次に

cout << a + b << "\n";


の次の命令文


int c = a + b;


ですね


int c = a + b;


が実行されると


この場合はちゃんと


数値の型変換が起こり


cには


3が格納されることになります


return c;


により


function(1.11, 2.22)


には


戻り値として


3


代入されることになるので


int i=function(1.11, 2.22);


の変数iには


3



代入されることになり


cout << i << "\n";


の実行結果は


3


表示されることになります


次に


float j = function(1.11, 2.22);


に御注目下さい



function(1.11, 2.22);


が実行されたときの戻り値は


float型💖💖💖の変数jに格納されることになります


すると


function(1.11, 2.22);


が実行されるとき


T function(T a, T b) {


cout << a + b << "\n";


T c = a + b;


return c;

}


Tにfloatが代入され

👇

float function(float a, float b) {


cout << a + b << "\n";


float c = a + b;

return c;

}


さらに


aに1.11

bに2.22

代入された状態で


float function(float a, float b) {

cout << a + b << "\n";

float c = a + b;


return c;

}

が実行されることになります


となると


float aに1.11

float bに2.22


が代入されることになるので


変数aには1.11

変数bには2.22


代入されることになりそうですが


実は


引数部分の


float a

float b



float型の形式でメモリにデータを格納するという機能をはたしていません



つまり


T function(T a, T b) {

cout << a + b << "\n";

T c = a + b;

return c;

}



Tにfloatが代入された


float function(float a,float b) {

cout << a + b << "\n";

float c = a + b;


return c;

}

が実行されるといっても


引数部分の

float a

float b



floatは型としての役割を果たしていないというわけです


この場合は


cout << a + b << "\n";


の実行結果は


3.33


が表示されていますが


float a

float b


に関わらず


cout << a + b << "\n";


の実行結果は


3.33


が表示されます


次に


float c = a + b;


が実行されると


cには


3.33が格納されることになります


return c;


により


function(1.11, 2.22)


には


戻り値として


3.33


代入されることになるので


float i=function(1.11, 2.22);


の変数iには


3.33



代入されることになり


cout << i << "\n";


の実行結果は


3.33


表示されることになります」



マックス「??


な、なんか


関数テンプレートは微妙・・・だな


おかしなビルド実行結果じゃないか?」


ソーラー「関数テンプレートは


どちらかというと


にもちいられます


自作関数の引数となっている変数に数値が代入されるといっても


その変数の型に合わせて代入される数値の型変換はおこりません


T function(T a, T b)



Tに


intが代入されようとも


floatが代入されようとも


変数a,変数bに格納される数値データは


代入される数値データが


整数値なら整数値


実数値なら実数値のままです


つまり


関数テンプレート


T function(T a, T b) {

cout << a + b << "\n";

T c = a + b;


return c;

}

のTに


intが代入されたとき


int function(int a, int b) {

cout << a + b << "\n";

int c = a + b;

return c;

}


が実行されることになり



T function(T a, T b) {

cout << a + b << "\n";

T c = a + b;


のTに


floatが代入されたとき


float function(float a, float b) {

cout << a + b << "\n";

float c = a + b;

return c;

}


が実行されることになりますが


これらの2つで違いが出てくるのは




まず




int👇ここ function(int a, int b) {

cout << a + b << "\n";

|int c = a + b;

return c;

}


float👇ここ function(float a, float b) {

cout << a + b << "\n";

|float c = a + b;

return c;

}


の👇で示される


戻り値を格納する型の部分ですね


戻り値は


int型に返されると整数値となり


float型に返されると実数値となりますね



次に


|int function(int a, int b) {

cout << a + b << "\n";

int👇ここ c = a + b;

return c;

}



|float function(float a, float b) {

cout << a + b << "\n";

float👇ここ c = a + b;

return c;

}


の👇で示される


a+bの値を格納する変数cの型の


int

float

の部分ですね


int型の変数cにa+bが代入されると


変数cに格納される値は整数値となり


float型の変数cにa+bが代入されると


変数cに格納される値は値は実数値となりますね


そして


違いが出てこないのが


cout << a + b << "\n";



a+bの値です


function(1.11, 2.22)


が実行されると


引数が


int a, int b


に関わらず


a+b


の値は


3.33


となります


もちろん


引数が


float a, float b


の場合でも


a+b


の値は


3.33


になりますが


引数が


float a, float b


であることと


a+b


の値が


3.33


となることは関係がありません」


ぶーにゃん「にゃんと・・・」






  • Twitterで共有
  • Facebookで共有
  • はてなブックマークでブックマーク

作者を応援しよう!

ハートをクリックで、簡単に応援の気持ちを伝えられます。(ログインが必要です)

応援したユーザー

応援すると応援コメントも書けます

新規登録で充実の読書を

マイページ
読書の状況から作品を自動で分類して簡単に管理できる
小説の未読話数がひと目でわかり前回の続きから読める
フォローしたユーザーの活動を追える
通知
小説の更新や作者の新作の情報を受け取れる
閲覧履歴
以前読んだ小説が一覧で見つけやすい
新規ユーザー登録無料

アカウントをお持ちの方はログイン

カクヨムで可能な読書体験をくわしく知る