[解決済み] C++のファンクターとその使い方とは?
質問
C++でファンクターについてよく聞きます。どなたか、ファンクターとは何か、どのような場合に有用か、概要を教えていただけませんか?
どのように解決するのですか?
ファンクタとは、要するにoperator()を定義したクラスです。これにより、関数のように見えるオブジェクトを作成することができます。
// this is a functor
struct add_x {
add_x(int val) : x(val) {} // Constructor
int operator()(int y) const { return x + y; }
private:
int x;
};
// Now you can use it like this:
add_x add42(42); // create an instance of the functor class
int i = add42(8); // and "call" it
assert(i == 50); // and it added 42 to its argument
std::vector<int> in; // assume this contains a bunch of values)
std::vector<int> out(in.size());
// Pass a functor to std::transform, which calls the functor on every element
// in the input sequence, and stores the result to the output sequence
std::transform(in.begin(), in.end(), out.begin(), add_x(1));
assert(out[i] == in[i] + 1); // for all i
ファンクターにはいくつか良い点があります。ひとつは、通常の関数と違って、状態を含むことができることです。上の例では、あなたが与えたものに42を足す関数を作っています。しかし、この42という値はハードコードされたものではなく、ファンクタのインスタンスを作成したときにコンストラクタの引数として指定されたものです。コンストラクタを別の値で呼び出すだけで、27を足す別の加算器を作ることができます。これによって、うまくカスタマイズできるのです。
最後の行にあるように、std::transform や他の標準ライブラリのアルゴリズムなど、他の関数への引数としてファンクタを渡すことはよくあります。普通の関数ポインタでも同じことができますが、上で述べたように、ファンクタは状態を含むので、より柔軟に "カスタマイズすることができます(もし私が関数ポインタを使いたかったら、その引数に正確に1を加える関数を書かなければなりません。ファンクタは一般的で、初期化したものを何でも追加します)、また、より効率的である可能性もあります。上の例では、コンパイラはどの関数が
std::transform
を呼び出す必要があります。呼び出すべきは
add_x::operator()
. つまり、その関数呼び出しをインライン化することができるのです。これによって、ベクトルの各値に対して手動で関数を呼び出した場合と同じように効率的になります。
もし、関数ポインターを渡したとしたら、コンパイラはそれがどの関数を指しているのかすぐにわからないから、かなり複雑なグローバル最適化をしない限り、実行時にポインターの参照を解除してから呼び出さなければならない。
関連
-
[解決済み】 unsigned int vs. size_t
-
[解決済み】c++でstd::vectorを返すための効率的な方法
-
[解決済み] 数値定数の前にunqualified-idを付けて、数値を定義することを期待する。
-
[解決済み】std::cin.getline( ) vs. std::cin
-
[解決済み】c++で.txtファイルから2次元の配列に読み込む
-
[解決済み] explicit キーワードの意味は?
-
[解決済み] ルール・オブ・スリーとは?
-
[解決済み] C++11では、標準化されたメモリモデルが導入されました。その意味するところは?そして、C++プログラミングにどのような影響を与えるのでしょうか?
-
[解決済み】C/C++の"-->"演算子とは何ですか?
-
[解決済み】C++11のラムダ式って何?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】getline()が何らかの入力の後に使用されると動作しない 【重複あり
-
[解決済み】非静的メンバ関数への参照を呼び出す必要がある
-
[解決済み] error: 'ostream' does not name a type.
-
[解決済み】IntelliSense:オブジェクトに、メンバー関数と互換性のない型修飾子がある
-
[解決済み】テンプレートの引数1が無効です(Code::Blocks Win Vista) - テンプレートは使いません。
-
[解決済み】浮動小数点例外エラーが発生する: 8
-
[解決済み】CMakeエラー at CMakeLists.txt:30 (project)。CMAKE_C_COMPILER が見つかりませんでした。
-
[解決済み】C++ - 適切なデフォルトコンストラクタがない [重複]。
-
[解決済み】デバッグアサーションに失敗しました
-
[解決済み】'std::cout'への未定義の参照