C++でC#のActionを再現してみたい
そう思ってしまったので勢いに任せて手を動かしました。
初めにC++でC#にあるActionクラスを再現できないか勢いに任せてやった試みのお話です。
1時間ぐらいで切り上げましたが、その過程を残してみます。
再現できたこと
- 呼び出す関数の登録
- 登録済みの関数を呼び出す
上記2つは再現できました。
しかし、登録済みの関数を登録解除する、という機能のみ実現できてないです…
以下がコードです
lambda_sample.h
#ifndef LAMBDA_SAMPLE_H
#define LAMBDA_SAMPLE_H
#include <vector>
#include <iostream>
#include <functional>
using std::vector;
using std::cout;
class lambda_sample
{
private:
vector<std::function<void()>> actions;
public:
lambda_sample()
{
}
~lambda_sample()
{
}
void add_action(std::function<void()> action)
{
actions.push_back(action);
}
void remove_action(std::function<void()> action)
{
for (int i = 0; i < actions.size(); ++i)
{
if (&action == &actions[i])
{
actions.erase(actions.begin() + i);
}
}
}
void call_all()
{
for (auto element : actions)
{
element();
}
}
};
#endif // LAMBDA_SAMPLE_H
lambda_sample.cpp
#include "lambda_sample.h"
#include <iostream>
using std::cout;
using std::cin;
int main()
{
lambda_sample func_array{};
auto a = [] { cout << "a invoked" << '\n'; };
auto b = [] { cout << "b invoked" << '\n'; };
auto c = [] { cout << "c invoked" << '\n'; };
cout << "a address : " << &a << '\n';
cout << "b address : " << &b << '\n';
cout << "c address : " << &c << '\n';
func_array.add_action(a);
func_array.add_action(b);
func_array.add_action(c);
func_array.call_all();
func_array.remove_action(a);
func_array.call_all();
return 0;
}
そして以下が実行時のコンソールへの出力
a add : 000000937D6FF934
b add : 000000937D6FF954
c add : 000000937D6FF974
a invoked
b invoked
c invoked
a invoked
b invoked
c invoked
上記の出力を見て考えたこと
-
「ラムダ式のアドレス同じところだったのか」
(1).アドレスよく見たら違いました... - 「std::vectorの中身のアドレスはどうやろ」
1.に関しては匿名関数、使い捨ての関数だからなのでしょう。
2.に関しては配列に格納しているから先頭アドレスが返るのだと勝手に思っています