我刚刚发现了一些东西,因为它获取当前函数的名称或获取调用者的名称,获取一些变体或将名称称为字符串。
我想要的是获取我在参数中传递的函数的名称。像这样:
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;
}
感谢。
编辑:根据@Jose的建议,这是一个非常接近的代码。
thread_local const char * m_last_function_called = "";
#define register_function() {m_last_function_called = __FUNCTION__;}
inline const char * get_last_function() { return m_last_function_called; }
// 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 print_last_func()
{
static std::mutex sync_cout;
std::lock_guard<std::mutex> l(sync_cout);
std::cout << get_last_function() << std::endl;
}
bool interruptFooTimer = false;
int FooTimer()
{
register_function();
print_last_func();
std::cout << "FooTimer.start" << std::endl;
int t = 0;
while(t<10)
{
if(interruptFooTimer==false)
{
sleep(1);
t++;
std::cout << "\tt=" << t << std::endl;
}
else
{
return -1;
}
}
std::cout << "FooTimer.end" << std::endl;
return 0;
}
void CallTrd(int (*f)())
{
std::thread TrdTemp(f);
TrdTemp.detach();
TrdTemp.~thread();
print_last_func();
}
int main()
{
CallTrd(FooTimer);
print_last_func();
int c = 0;
while(c<15)
{
if(c==7) {interruptFooTimer=true;}
sleep(1);
c++;
std::cout << "c=" << c << std::endl;
print_last_func();
}
return 0;
}
观察我在不同时刻调用print_last_func()并获得与变量中初始化值相同的值。此示例代码在不使用join()的情况下调用线程,因为我不能等待线程完成并且还实现了detach()和〜thread来完成我的程序而没有任何异常。我正在使用interruptFooTimer安全地“终止”我的线程。 我错过了什么来获得在register_function中获得的全局值?
答案 0 :(得分:1)
你做不到。在编译期间,编译器会扩展__FUNCTION__
。您无法在运行时获取此信息。
答案 1 :(得分:0)
使用辅助宏:
#define Foo(x) FooHelper(#x, x)
void FooHelper(const char *f_name, void (*f)())
{
cout << f_name;
}
答案 2 :(得分:0)
我不知道你为什么要这样做,但我希望它能用于调试目的。显然,最简单的方法是将__FUNCTION__
作为参数传递出去。但在我看来,这是一个更好的方法。
例如,您可以使用全局变量:
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;
}
}
当然,这不会在多线程中为您提供正确的结果,但您可以使用thread_local const char * g_last_function_called = ""
变量来解决这个问题。
我之所以喜欢这种方法,是因为你需要做的就是将它从项目中移除它只是一个简单的&#34;查找和替换&#34; register_function(),因为它使用普通指针,所以根本不能让你的程序变慢。
编辑:这就是我测试代码的方式
void print_last_func()
{
static std::mutex sync_cout;
std::lock_guard<std::mutex> l(sync_cout);
std::cout << get_last_function() << std::endl;
}
void HelloWorld1()
{
register_function();
print_last_func();
}
void HelloWorld2()
{
register_function();
print_last_func();
}
int main()
{
register_function();
std::thread t1(HelloWorld1);
std::thread t2(HelloWorld2);
print_last_func();
t1.join();
t2.join();
return 0;
}
我得到:HelloWorld1,HelloWorld2和main
答案 3 :(得分:0)
正如其他人已经指出的那样,你不能直接这样做。
首先,我会使用std::function而不是原始函数指针和std::string来保存函数的名称。
我也会像这样包装它们:
sudo bash
echo "test" > test.html
然后您可以这样使用它:
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;
}
的函数名称不同。