2016-07-27 18 views
-1

私はコーディングスキルを向上させるためにC言語を使用しています。値を返すときの関数ポインタ

以下に示すように、私が探していた問題を簡単に見つけて、多くの問題を処理するときに手配したいので、簡単なプログラムを設計しました。ここで

は私のヘッダファイル

#pragma once 
#ifndef PROBLEM_H 
#define PROBLEM_H 

namespace PROBLEM_1 { int do_main(); } 

typedef int(*MAINFUNC)(); 

#endif 

そして、以下は私のソースファイルです。

#include "problems.h" 
#include <stdio.h> 
#include <iostream> 
#include <string> 
#include <algorithm> 
#include <map> 
using namespace std; 

typedef int(*MAINFUNC)(void); 

map<string, MAINFUNC> func_map; 

void initialize_problem_map(void) { 
    func_map["problem_1"] = PROBLEM_1::do_main; 
} 

namespace PROBLEM_1 { 
    int do_main(void) { 
     cout << "hi" << endl; 
     return 1; 
    } 
} 

int main(void) { 
    string problem; 

    initialize_problem_map(); 
    cin >> problem; 

    if (func_map.find(problem) != func_map.end()) 
     return (*(func_map[problem]))(); 


    return -1; 
} 

I入力 "PROBLEM_1"、その後、名前空間PROBLEM_1でdo_main機能が実行されます。私はこのデザインが複数のコーディングの問題を整理するのに役立つと思います。

しかし、私の質問は以下の2つのコード行についてです。

if (func_map.find(problem) != func_map.end()) 
    return (*(func_map[problem]))(); 

ご覧のとおり、メイン関数の戻り値の型は "int"です。しかし、if節では、関数ポインタを返すと思います。したがって、私はその振る舞いを返すものが主関数の戻り値の型と一致しないと考えました。しかし、私の驚いたことに、それはうまくいった。

返されるタイプに関するこの手順について説明できますか?

+0

"私はC言語を使用しています"と記述しますが、タグとコードが示すとおり、C++を使用しています。 –

+0

トピックから: 'func_map.find'は、見つかった項目または' end() 'にイテレータを返します。あなたは明らかにそれを知っていますが、そのイテレータを使って 'func_map [problem]'とまったく同じルックアップを実行する必要性を排除することもできます。例: 'map <文字列、MAINFUNC> :: iterator it = func_map.find(問題); ['std :: map :: at'](http://en.cppreference.com/w参照)も参照してください。/cpp/container/map/at)を参照してください。[C++ 11のstd :: function](http://en.cppreference.com/w/cpp/utility/functional/function)関数ポインタの必要性を排除します。 – user4581301

+0

もしあなたがC++を使っているなら(私はあなたがマップ、文字列、iostreamなどを見ることができると仮定しています)、stdio.hの代わりにcstdioを使うべきです。私は本当になぜあなたはそれを必要としているのかわかりません:)。 – Lehu

答えて

2

func_map[problem]実際には、関数ポインタが返されます。演算子()を適用すると、関数が呼び出され、式の結果はintになります。呼び出しの前に関数ポインタを省略することはオプションです。これは、関数ポインタを初期化するための関数名をとるオプションのアドレスで対称的です。

0

findはイテレータを返します。このイテレーターが終了した場合、問題はマップに存在しません。終了していないので、それが存在し、戻りラインで[]で取得したポインタ関数を使用して呼び出します。

1

実際

func_map[problem] 

がポインタです。ただし、*とポインタ間接参照:

*(func_map[problem]) 

と)(追加することで機能を呼び出す:

(*(func_map[problem]))() 

"INT" を返します。

関連する問題