C++ でコールバック関数を作成する
- C++ で異なる表記法でコールバック関数を宣言する
-
対応するキーを持つ複数のコールバック関数を C++ に格納するには、
std::mapを利用する - C++ でユーザ入力に基づいて特定のコールバック関数を呼び出す
この記事では、C++ でコールバック関数を使用する方法をいくつか解説します。
C++ で異なる表記法でコールバック関数を宣言する
コールバックとは、プログラムの実行中に後で呼び出されるように、引数として他の関数に渡される関数(コード内のサブルーチンなど)のことです。
コールバック関数は、言語固有のツールを使用して実装することができますが、C++ では、すべての関数がコール可能なオブジェクトとして知られています。呼び出し可能なオブジェクトには、伝統的な関数、関数へのポインタ、ラムダ式、bind 作成オブジェクト、() 演算子をオーバーロードするクラス、<functional> ヘッダで定義された std::function 型のオブジェクトなどがあります。
以下の例では、伝統的な 2つの関数 addTwoInts/subtructTwoInts と、変数 modOfTwoInts1 に格納された 1つのラムダ式、および std::function 型の modOfTwoInts2 を定義しています。これらの関数は整数の基本的な演算子 +、-、modulo を実装しています。
#include <functional>
#include <iostream>
#include <map>
#include <vector>
using std::cin;
using std::cout;
using std::endl;
using std::function;
using std::map;
using std::string;
int addTwoInts(int i, int j) { return i + j; }
int subtructTwoInts(int i, int j) { return i - j; }
int main() {
auto modOfTwoInts1 = [](int i, int j) { return i % j; };
cout << "modOfTwoInts1(10, 3) = " << modOfTwoInts1(10, 3) << endl;
cout << "addTwoInts(10, 3) = " << addTwoInts(10, 3) << endl;
cout << "subtructTwoInts(10, 3) = " << subtructTwoInts(10, 3) << endl;
function<int(int, int)> modOfTwoInts2 = [](int i, int j) { return i % j; };
cout << "modOfTwoInts2(10, 3) = " << modOfTwoInts2(10, 3) << endl;
return EXIT_SUCCESS;
}
出力:
modOfTwoInts1(10, 3) = 1
addTwoInts(10, 3) = 13
subtructTwoInts(10, 3) = 7
modOfTwoInts2(10, 3) = 1
対応するキーを持つ複数のコールバック関数を C++ に格納するには、std::map を利用する
コールバック関数を利用する一般的な方法は、vector や map のようなデータ構造体にそれらを格納することで、プログラム実行時に簡単にアクセスして特定の関数を呼び出すことができます。この例では、map コンテナを選択して、算術演算子を文字列としてキーに、対応する関数を値に格納しています。このコード例では、コンソールには何も出力していないことに注意してください。
#include <functional>
#include <iostream>
#include <map>
using std::cin;
using std::cout;
using std::endl;
using std::function;
using std::map;
using std::string;
int addTwoInts(int i, int j) { return i + j; }
int subtructTwoInts(int i, int j) { return i - j; }
int main() {
auto modOfTwoInts1 = [](int i, int j) { return i % j; };
auto subtruct = subtructTwoInts;
map<string, int (*)(int, int)> op_funcs;
op_funcs.insert({"+", addTwoInts});
op_funcs.insert({"%", modOfTwoInts1});
op_funcs.insert({"-", subtruct});
return EXIT_SUCCESS;
}
C++ でユーザ入力に基づいて特定のコールバック関数を呼び出す
前節の結果として、map コンテナに格納されたコールバック関数を実用的な方法で利用する必要があります。その一つの方法は、ユーザから演算子シンボルを受け取り、それをキーとして map コンテナに渡して対応する関数オブジェクトを呼び出すことです。このメソッドは UI アプリケーションでイベントを処理するためによく使われます。呼び出された関数に任意の整数の引数 (10, 3) を渡していることに注意してください。
#include <functional>
#include <iostream>
#include <map>
using std::cin;
using std::cout;
using std::endl;
using std::function;
using std::map;
using std::string;
int addTwoInts(int i, int j) { return i + j; }
int subtructTwoInts(int i, int j) { return i - j; }
int main() {
auto modOfTwoInts1 = [](int i, int j) { return i % j; };
auto subtruct = subtructTwoInts;
map<string, int (*)(int, int)> op_funcs;
op_funcs.insert({"+", addTwoInts});
op_funcs.insert({"%", modOfTwoInts1});
op_funcs.insert({"-", subtruct});
string user_input;
cout << "\nType one of the following ops\n"
"for integers 10 and 3 to be used:\n"
"1) + 2) - 3) % \n";
cin >> user_input;
cout << op_funcs[user_input](10, 3);
return EXIT_SUCCESS;
}
出力(入力が + の場合):
Type one of the following ops
for integers 10 and 3 to be used:
1) + 2) - 3) %
+
13
