2016-11-17 83 views
1

给定一个只包含单个函数定义的任意C++源代码,我尝试捕获该函数的名称(可以是任意的)。为此,我假设在函数的名称和参数列表之间没有符号/词,即,我正在查找第一个出现的括号符号“(”(它启动函数的参数列表)并捕捉它前面的单词(其中我认为它是函数的名称);这个过程是正确的吗?捕获函数名称

不幸的是,C++规范(http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4296.pdf第207页)对我来说是不可理解的。

回答

2

我正在寻找第一个出现的括号符号“(”(它启动函数的参数列表)并捕获它前面的单词(我认为它是该函数的名称);是由此出发正确

不,这是不正确的。在最基本的情况下,这是正确的:?

int foo() { 
    return 1; 
} 

但是,如果你想支持任何功能(非模板)那么这种情况将会失败:

std::function<int(int)> foo() { 
    return [](int) { return 1; }; 
} 

检查返回类型和函数名之间的空白也是一个坏主意,因为大部分空格都被编译器忽略,即这将失败:

std::function< int (int) > foo() { 
    return [](int) { return 1; }; 
} 

那么,怎么办你做到了吗? 您需要构建一个部分C++分析器来分析函数定义。

您没有其他办法来支持非模板功能,如果添加模板功能,它将更加困难。返回类型可以包含任何字符,没有特殊的分隔符可用。

你也可以有函数指针,它们是内置的语言并打破下面的空白+括号搜索。您将需要建立一个解析器:(

为了简化,你可以禁止任何 #include声明,这只会导致像第一个基本功能。如果这是不是检查的 (符号的情况下,和之前获得了这个词,为什么不找第一空白,并获得空白和 (之间的一切?

std::string get_function_name(std::string source) { 
    auto whitespace = source.find(' '); 
    if (whitespace == std::string::npos) 
     return ""; 

    auto open_bracket = source.find('(', whitespace); // find (after whitespace 
    if (open_bracket == std::string::npos) 
     return ""; 

    return source.substr(whitespace + 1, open_bracket - whitespace); 
} 

2

函数返回类型可能非常奇怪,例如

void foo(int t){} 

void (* returnFptr())(int t){ 
    return foo; 
} 

returnFptr()返回类型是void(*)(int)。因此,第一个左括号不保证位于函数名称和参数列表之间。