2016-11-17 74 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)。因此,第一個左括號不保證位於函數名稱和參數列表之間。