2016-07-27 85 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; 
} 

如果我输入 “PROBLEM_1”,那么,在命名空间PROBLEM_1的do_main功能将被执行。我认为这种设计可以帮助我组织多重编码问题。

但是,我的问题是关于这两个代码行如下。

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

正如你所看到的,主要函数的返回类型是“int”。但是,在if子句中,我认为它返回函数指针。因此,我认为那些返回的行为与主函数的返回类型不匹配。但是,令我惊讶的是,它运作良好。

你能解释这个程序有关返回类型?

+0

您编写的“我正在使用C语言”,但正如您的标记和代码所示,您正在使用C++。 –

+0

off topic:'func_map.find'返回一个迭代器到找到的项目或'end()'。你很清楚,但你也可以使用该迭代器来消除对func_map [problem]执行完全相同查找的需要。例如:'map :: iterator it = func_map.find(problem); if(it!= func_map.end())return(*(it-> second))();'See also ['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等),那么你应该使用cstdio而不是stdio.h。虽然我不知道你为什么需要它:)。 – Lehu

回答

2

func_map[problem]实际上会产生一个函数指针。在其上应用运算符(),该函数被调用并且表达式产生在int中。在调用之前取消引用函数指针是可选的。这与一个可选地址对称,该地址采用函数名称来初始化函数指针。

0

查找返回一个迭代器;如果这个迭代器结束了,那么这个问题在地图中不存在;因为它不是结束的,所以它存在,然后在返回行中使用[]获得的指针函数来调用它。

1

事实上

func_map[problem] 

是一个指针。但是,取消引用指针与*:

*(func_map[problem]) 

和呼叫功能加入():

(*(func_map[problem]))() 

返回 “INT”。