とても簡単です。名前から年齢関数へのマップを作成します。
typedef は関数ポインタをより簡単にし、静的ローカル マップは関数ポインタを 1 回だけ初期化してから結果を「キャッシュ」します。順序付けられていないマップは、この種のものに最適です。
C++11:
void age(const std::string& NAME){
static const std::unordered_map<std::string, void(*)()> age_lut = {
{"John",John_age},
{"Tom",Tom_age},
{"Kate",Kate_age},
{"Cathy",Cathy_age},
};
return age_lut.at(Name); //throws std::out_of_range if it doesn't exist
}
C: (ここでは怠け者なので、C++ のようなハッシュの代わりに線形マップを使用します)
typedef void(*)() get_age_func_type;
typedef struct {
const char* name;
get_age_func_type func;
} age_lut_type;
age_lut_type age_lookup_table[] = {
{"John",John_age},
{"Tom",Tom_age},
{"Kate",Kate_age},
{"Cathy",Cathy_age},
};
const unsigned age_lookup_table_size =
sizeof(age_lookup_table)/sizeof(age_lut_type);
bool age(char* NAME){
bool found = false;
//if you have a large number of functions,
//sort them in the initialization function, and
//use a binary search here instead of linear.
for(int i=0; i<age_lookup_table_size ; ++i) {
if (stricmp(age_lookup_table[i], NAME)==0) {
age_lookup_table[i].func();
found = true;
break;
}
}
return found;
}
このコードはすべて私の頭の中で思い浮かんだものであり、おそらくそのままではコンパイルできません。
実際には、個人ごとに関数を持たず、代わりにデータを使用することを強くお勧めします。絶対に必要な場合は、文字列の代わりに列挙を使用してそれらを識別します。