获取std :: function的名称

hr0*_*r0m 21 c++ c++11 std-function

在下面的玩具示例中,我想获得一个函数的名称.函数本身作为std::function参数给出.在C++中是否可以获取std::function对象的名称?

void printName(std::function<void()> func){
    //Need a function name()
    std::cout << func.name();
}

void magic(){};

//somewhere in the code
printName(magic());

output: magic
Run Code Online (Sandbox Code Playgroud)

否则我必须将函数的名称作为第二个参数.

Bat*_*eba 27

不,没有.编译出函数名称(如变量名称),因此它们在运行时不可见.

你最好的选择是传递你自己建议的功能名称(使用a std::string或a const char*).(或者你可以建立一个__func__在C++ 11中引入的解决方案.)


tho*_*san 13

答案是否定的,但你可以做出像

template<class R, class... Args>
class NamedFunction
{
public:
    std::string name;
    std::function<R(Args...)> func;
    NamedFunction(std::string pname, std::function<R(Args...)> pfunc) : name(pname), func(pfunc)
    {}
    R operator()(Args&&... a)
    {
       return func(std::forward<Args>(a)...);
    }
};
Run Code Online (Sandbox Code Playgroud)

然后定义一个预处理器

#define NAMED_FUNCTION(var, type, x) NamedFunction<type> var(#x,x)
...
NAMED_FUNCTION(f, void(), magic);
Run Code Online (Sandbox Code Playgroud)


Sir*_*Guy 7

鉴于std::function它有一个成员函数调用target_type,它返回typeid存储的函数对象.这意味着你可以做到

void printName(std::function<void()> func){
    //Need a function name()
    std::cout << func.target_type().name();
}
Run Code Online (Sandbox Code Playgroud)

这将返回每个类型唯一的实现定义字符串.使用Visual Studio,此字符串已经是人类可读的.使用gcc(或者它的glibc?我不知道谁会详细说明),你需要abi::__cxa_demangle在包含之后使用<cxxabi.h>以获得类型名称的人类可读版本.

编辑
正如Matthieu M.指出的那样,给定一个函数指针,由此返回的类型将只是函数的签名.例如:

int function(){return 0;}
printName(function);
Run Code Online (Sandbox Code Playgroud)

这将输出(假设您在必要时进行了解码)int (*)(),这不是函数的名称.

这个方法适用于类:

struct Function
{
    int operator()(){return 0;}
};

printName(Function{});
Run Code Online (Sandbox Code Playgroud)

这将Function根据需要打印,但不适用于函数指针.