Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/131.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何获得传入参数的函数名?_C++_Arguments - Fatal编程技术网

C++ 如何获得传入参数的函数名?

C++ 如何获得传入参数的函数名?,c++,arguments,C++,Arguments,我刚刚发现了一些东西,比如获取当前函数的名称或获取调用方的名称,还有一些变量可以获取或调用名称作为字符串 我想要的是获取我在参数中传递的函数的名称。像这样: void Bar() { //do something } void Foo(void (*f)()) { //this will output: Foo std::cout << __FUNCTION__ << std::endl; //How do I get the name passed to f? (i

我刚刚发现了一些东西,比如获取当前函数的名称或获取调用方的名称,还有一些变量可以获取或调用名称作为字符串

我想要的是获取我在参数中传递的函数的名称。像这样:

void Bar()
{
//do something
}

void Foo(void (*f)())
{
//this will output: Foo
std::cout << __FUNCTION__ << std::endl;

//How do I get the name passed to f? (in this case: Bar)
}

int main()
{
Foo(Bar);
return 0;
}
void Bar()
{
//做点什么
}
无效Foo(无效(*f)()
{
//这将输出:Foo

std::cout您不能。
\uuuuu函数\uuuuu
在编译期间由编译器展开。您无法在运行时获取此信息。

使用帮助程序宏:

#define Foo(x) FooHelper(#x, x)
void FooHelper(const char *f_name, void (*f)())
{
    cout << f_name;
}
#定义Foo(x)fooheloper(#x,x)
void FooHelper(常量字符*f_名称,void(*f)()
{

我不知道你为什么要这样做,但我希望这是为了调试。显然,最简单的方法是将
\uuuu函数\uuuuu
作为一个参数传递。但在我看来,有一个更好的方法

例如,您可以有一个全局变量:

thread_local const char * g_last_function_called = ""; 

#define register_function() { g_last_function_called = __FUNCTION__; }
inline const char * get_last_function() { return g_last_function_called; }

void Bar()
{
    register_function() 
}

void Foo(void (*f)())
{
    std::cout << get_last_function() << std::endl;
}

void my_func_that_doesnt_accept_nulls(CClass * p) 
{
     if (p == nullptr)
     {
        std::cout << " function" << get_last_function();
        std::cout << "passed a bad pointer, fix it" << std::endl;
        return;
     }
}

我得到:HelloWorld1、HelloWorld2和main

正如其他人已经指出的,您不能直接这样做

首先,我将使用而不是原始函数指针来保存函数名

我也会这样总结:

template<class T>
struct Functor
{
    std::function<T> functor_;
    std::string name_;

    Functor(const std::function<T>& functor, const std::string& name)
        : functor_(functor)
        , name_(name)
    {}
};
int main() 
{
    auto f = FUNCTOR(void(), Bar);
    return 0;
}

请注意,如果采用这种方法,函数名可能与使用
\uuuu function\uuuu
生成的函数名不同。

将名称作为单独的参数传递?@Mohamad您可能会说:void Foo(void(*f)(,std::string Fname)和int main(){Foo(Bar,Bar);}查看我的答案。谢谢。它对简单函数非常有效,但实际上你对多线程的可能性是正确的。相同的代码,但使用线程\u本地并更改g\u last\u函数\u调用的m\u last\u函数,register\u函数()不会“更新值”m_的最后一个函数_称为variable。我还必须更改const char*的all,我的编译器指示从char*到const char*的转换无效。我正在这里进行一些测试。register_函数()正确调用,并更新正确调用的m_last_函数的值。我在register_函数中放置了一个cout,并显示了正确的名称。但是,在get_last_函数()中它返回调用的m_last_函数的原始初始化值。我遗漏了什么?线程的值与线程一起被销毁?get_last_函数()没有获得正确的变量范围?@Amperage我输入了一个错误。在所有位置使用g_variable_name或m_variable_name。不要混合使用它们(我编辑了我的回复,你得到了第二个版本)。我刚刚测试了创建多个线程的代码,它可以工作(我以前没有测试过代码)。我想请你帮个大忙,看看我在问题版本中插入的代码。我遗漏了什么?非常感谢。print_last_func()内部CallTrd应该打印main,但这不是因为在调用main上的CallTrd()之前没有使用register_函数。除非这不是您想要做的,并且您想要打印您在FooTimer中注册的内容,这在线程_local bcz what u在FooTimer中注册的内容是不可能的(例如,线程id 5)将在thrad_local_6_var和calltrd中注册该名称,您试图从线程_local_5_var中检索函数名,这两个变量不同。
template<class T>
struct Functor
{
    std::function<T> functor_;
    std::string name_;

    Functor(const std::function<T>& functor, const std::string& name)
        : functor_(functor)
        , name_(name)
    {}
};
void Bar()
{
    // do something
}

void Foo(const Functor<void()>& functor)
{
}

int main() 
{
    Functor<void()> f(std::bind(Bar), "Bar");
    Foo(f);
    return 0;
}
#define FUNCTOR(t, x, ...) Functor<t>(std::bind(&x, __VA_ARGS__), #x)
int main() 
{
    auto f = FUNCTOR(void(), Bar);
    return 0;
}