引数や戻り値が異なる関数ポインタをキュー(std::queue)に詰めたいです。
たとえば、以下のFUNCPTR1とFUNCPTR2は、同じキューに詰めることはできますか?
typedef void (*FUNCPTR1)();
typedef int (*FUNCPTR2)(int a);
std::functionを使えばできるのでしょうか・・・?
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/09/26 10:49
回答3件
0
ベストアンサー
引数や戻り値が異なる関数ポインタをキュー(std::queue)に詰めたいです。
技術的に実装不可能ではないですが、設計を見直すことを強くおすすめします。
std::functionを使えばできるのでしょうか・・・?
std::function
クラステンプレートでは実装不可能です。std::function<R(Args...)>
のように戻り値型R
と引数型リストArgs...
を明示する必要があるため、「引数や戻り値が異なる関数ポインタ」を同一std::function
型で扱えません。
一応、どんなデータ型(任意の関数ポインタも含む)でも扱えるstd::any
クラスを使った実装コードの例を示します。呼び出し側では格納した型(FUNCPTR1
やFUNCPTR2
)を明示する必要があります。不一致の場合は、std::bad_any_cast
例外がスローされます。
Demo: https://wandbox.org/permlink/reO9fTJ9jkV1O4dr
cpp
1#include <any> 2#include <iostream> 3#include <queue> 4 5void f() 6{ 7 std::cout << "f()\n"; 8} 9 10int g(int a) 11{ 12 std::cout << "h(" << a << ")\n"; 13 return a * 2; 14} 15 16int main() 17{ 18 typedef void (*FUNCPTR1)(); 19 typedef int (*FUNCPTR2)(int a); 20 21 std::queue<std::any> q; 22 q.push(&f); 23 q.push(&g); 24 25 auto fp1 = std::any_cast<FUNCPTR1>(q.front()); 26 fp1(); 27 28 q.pop(); 29 30 try { 31 auto fp1 = std::any_cast<FUNCPTR1>(q.front()); 32 fp1(); 33 } catch (const std::bad_any_cast&) { 34 std::cout << "<mismatched>" << std::endl; 35 } 36 37 auto fp2 = std::any_cast<FUNCPTR2>(q.front()); 38 std::cout << fp2(10) << std::endl; 39}
投稿2019/09/26 10:10
編集2019/09/26 11:52総合スコア6191
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/09/26 10:53
2019/09/26 12:24
2019/09/27 01:01
0
味方や敵の戦うや逃げるといったコマンド(関数)をキューに詰めていき、詰め終わったら、キューからコマンドをひとつずつ取り出して、味方の攻撃や、敵の魔法などを順番に実行する、といった感じ
ラムダ式をキューにぶちこんでいく方法をおすすめします。
c++
1#include<functional> 2 3std::queue<std::function<void(void)>> que; 4que.emplace( [](){FUNCPTR1();} ); 5que.emplace( [this](){FUNCPTR2(m_variable);} ); 6 7while (!que.empty()) { 8 que.front()(); 9 que.pop(); 10} 11
投稿2019/09/26 12:23
総合スコア15149
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/09/27 00:55
2019/09/27 01:49
2019/09/27 05:04
2019/09/27 06:16
2019/09/27 06:36
0
総称ポインタを使えばとりあえず詰めることはできるけど,
このままだと詰めたものを取り出す側は一体どうやって使うのかが完全に謎.
何か使い方のヒントになる物を一緒にして詰める必要があると思う.
void F1(){} int F2( int ){ return 5; } int main() { std::queue< void * > Q; Q.push( F1 ); Q.push( F2 ); ... }
投稿2019/09/26 07:30
総合スコア11985
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。