質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

3回答

4019閲覧

c++ 関数ポインタで関数ポインタを引数に取る関数のアドレスを関数ポインタに入れられない原因が知りたい。

退会済みユーザー

退会済みユーザー

総合スコア0

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2019/04/11 05:23

このコードがエラーになるのですが関数を引数に取る関数ポインタを作ることかできないのでしょうか?

重大度レベル コード 説明 プロジェクト ファイル 行 抑制状態
エラー (アクティブ) E0090 関数を返す関数は使用できません

void func4( void(*fp)(void(*)(int a,string x)) , int b) { } int main() { srand((unsigned)time(NULL)); void(*fp)(void(*)(void*)(int, string), int) = func4; _getch(); return 0; }

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

こういうことでしょうか?
func4 の宣言は基本的に変わっていません。

C++

1#include <iostream> 2#include <string> 3 4void f1(int a, std::string x) 5{ 6 std::cout << "f1 ("; 7 std::cout << "a = " << a << ", "; 8 std::cout << "x = " << x << ")\n"; 9} 10 11void f2(void(*fp)(int, std::string)) 12{ 13 std::cout << "f2\n"; 14 fp(20, "hello"); 15} 16 17void func4(void(*fp)(void(*)(int a, std::string x)), int b) 18{ 19 std::cout << "func4 (b = " << b << ")\n"; 20 fp(f1); 21} 22 23int main() { 24 //void(*fp)(void(*)(void*)(int, string), int) = func4; 25 void (*fp)(void(*)(void(*)(int, std::string)), int) = func4; 26 fp(f2,10); 27}

実行してもあまり意味はないですが。

text

1func4 (b = 10) 2f2 3f1 (a = 20, x = hello)

以下追記
C/C++ の宣言は関数ポインターが絡むと非常にややこしくなりますね。
maisumakun さんの回答のように auto を使って変数を定義しておき typeid で型を表示させれば一発でわかります。

C++

1#include <iostream> 2#include <string> 3#include <typeinfo> 4 5void func4(void(*fp)(void(*)(int a, std::string x)), int b) 6{ 7} 8 9int main() { 10 auto fp = func4; 11 std::cout << typeid(fp).name() << '\n'; 12}

VC++ で実行すると

void (__cdecl*)(void (__cdecl*)(void (__cdecl*)(int,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)),int)

std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >std::string ですから、結局 void (__cdecl*)(void (__cdecl*)(void (__cdecl*)(int,std::string)),int) となり、__cdecl を削除すれば void (*)(void (*)(void (*)(int,std::string)),int) となります。

投稿2019/04/11 06:39

編集2019/04/11 08:30
Bull

総合スコア986

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

episteme

2019/04/11 12:35

autoに代入せんでもいい↓んじゃね? std::cout << typeid(func4).name() << '\n';
Bull

2019/04/11 12:41 編集

確かに。確認するだけならそうでした。
guest

0

C++

1void func4( void(*fp)(void(*)(int a,string x)) , int b)

誤:void(*fp)(void(*) (void*)(int, string) , int) = func4;
正:void(*fp)(void(*)(void(*)(int, string)), int) = func4;

関数プロトタイプ宣言が組み立てられているのであれば、「該当関数へのポインタ型」の導出はさほど難しくないと思います。(引数リスト部分はそのままコピー&ペーストですみますね)

関数プロトタイプ宣言:戻り値型 関数名(引数リスト)
関数ポインタ型変数の宣言:戻り値型 (*変数名)(引数リスト)

投稿2019/04/11 14:48

yohhoy

総合スコア6191

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

fpの型宣言が間違っています。void(*)(void*)(int, string)が「関数を返す関数へのポインタ」となってしまっています。

C++なら、手を抜きましょう。auto fp = func4;で済みます。

投稿2019/04/11 05:26

maisumakun

総合スコア145184

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2019/04/11 05:32

using やtypdefなど使えば楽にできることは知っているのですが 初学者ですので素の定義の仕方知りたいのですが提示コードのような書き方を教えてくれますか❓
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問