abraham_hilbert abraham_hilbert - 19 days ago 7
C++ Question

Capture function name

Given an arbitrary C++ source code that only comprises the definition of a single function, I try to capture the function's name (which can be arbitrary).

For this, I assume that there are no symbols/words between a function's name and its argument list, i.e., I'm looking for the first occurrence of the bracket symbol "

(
" (which initiate the function's argument list) and capture the word in front of it (of which I think it is the function's name); is this proceeding correct?

Unfortunately, the C++ specification (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4296.pdf p. 207) is incomprehensible for me.

Answer

I'm looking for the first occurrence of the bracket symbol "(" (which initiate the function's argument list) and capture the word in front of it (of which I think it is the function's name); is this proceeding correct?

No, it is no correct. In the most basic cases, this is true:

int foo() {
    return 1;
}

But if you want to support any function (non-template), then it will fail for this case:

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

Checking for the whitespace between the return type and the function name is also a bad idea, because most whitespaces are ignored by the compiler, i.e. this will fail:

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

So, how do you do it then? You would need to build a partial C++ parser to analyze the function definition.

You have no other way to support every non-template function, and if you add the template functions, it will be even harder. The return type can include any character, there is no special delimiter available.

To simplify, you could disallow any #include statements, which would only result in basic functions like the first one. If that is the case, instead of checking for the ( symbol and getting the word before, why not find the first whitespace and get everything between the whitespace and the (?

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);
}