たまにはプログラマらしく

ど〜も〜、PROGRESSの最近は「お兄ちゃん」より「兄さん」が好きなほう、tktkです。

久しぶりにコラムを書くということで、今まで自分が書いたものを見返してみたのですが、
なんというかしょうもないことばかりだったので、
たまにはプログラマらしくプログラムのことを書いてみようと思います。

・C++の配列とテンプレートのちょっとしたテクニックについて。

C++で配列を関数で操作したい場合にはこんな感じにすると思います。

////////////////////////////////////////////////////
void Add(int* ary, int size, int val){
 for(int i = 0; i < size; ++i)ary[i] += val;
}
////////////////////////////////////////////////////

使い方はこんな感じです。

/////////////////////////////////////
void Main(){
 int ary[5] = {0,1,2,3,4};
 Add(ary, 5, 2);
}
/////////////////////////////////////

このAdd関数を別の型でも使いたいという場合は

//////////////////////////////////////////
template<class T>
void Add(T* ary, int size, T val){
 for(int i = 0; i < size; ++i)ary[i] += val;
}
//////////////////////////////////////////

という風にAdd関数を変更すれば別の型でも使えますね。

/////////////////////////////////////
void Main(){
 int n_ary[5] = {0,1,2,3,4};
 int s_ary[3] = {0,1,2};
 Add(n_ary, 5, (int)2);
 Add(s_ary, 3, (short)3);
}
/////////////////////////////////////

さらにここでもう一工夫。

//////////////////////////////////////////
template<class T, int SIZE>
void Add(T (&ary)[SIZE], T val){
 for(int i = 0; i < SIZE; ++i)ary[i] += val;
}
//////////////////////////////////////////

こうすることで、型、配列サイズを気にすることなく使用できます。

//////////////////////////////////////////
void Main(){
 int n_ary[5] = { 0,1,2,3,4 };
 short s_ary[3] = { 0,1,2 };
 char c_ary[4] = { 0,1,2,3 };
 Add(n_ary, (int)1);
 Add(s_ary, (short)2);
 Add(c_ary, (char)4);
}
////////////////////////////////////////////////////

Add関数の第一引数「T (&ary)[SIZE]」の部分はあまり見かけない記述だと思いますが、
これは固定長配列の参照渡しの記述方法で、書き方は

型 (&変数名)[配列サイズ]

と書きます。それをテンプレートに対応させた形が

T (&ary)[SIZE]

になります(そのまんまですね)。


いかがだったでしょうか?
使い所があるかは微妙なところですが、
知っておいて損はないテクニックだと思います。


ちなみに戻り値で配列の参照を使う場合は

型 (&関数名(引数))[配列サイズ]

と書きます。

//////////////////////////////////////
int (&GetAry())[3]{
 static int s_ary[3] = {1,2,3};
 return s_ary;
}
//////////////////////////////////////

こんな感じです。

個人的にはJavaみたいな書き方(こんな感じ↓)

///////////////////////////////////////////
void SetAry(int ary[10])// 引数に渡すとき
int[10] GetAry() // 戻り値
///////////////////////////////////////////

ができればいいなと思うんですけどね。




tktk