/ / Как да се получи име на функция в параметри? - c ++, аргументи

Как да зададете име на функция в параметри? - c ++, аргументи

Току-що намерих нещо като да получа името на текущата функция или да получа името на обаждащия се, някои варианти да се получи или да се обадя на името като низ.

Искам да получа името на функцията, която предавах в аргументите. Като този:

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, за да завърша програмата си без никакво изключение. Прекъсващата фоторамка, която използвам за безопасно прекратяване "нишката ми. Какво ми липсва, за да получа глобална стойността, получена в register_function?

Отговори:

1 за отговор № 1

Не можеш. __FUNCTION__ се разширява от компилатора по време на компилацията. Не можете да получите тази информация по време на изпълнение.


0 за отговор № 2

Използвайте макрос за помощник:

#define Foo(x) FooHelper(#x, x)
void FooHelper(const char *f_name, void (*f)())
{
cout << f_name;
}

0 за отговор № 3

Както вече отбелязват другите, не можете да направите това директно.

Преди всичко бих използвал STD :: функция вместо на показалеца за сурова функция и STD :: низ задържане на името на функцията.

Аз също ще ги обвивам така:

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

Имайте предвид, че ако използвате този подход, името на функцията може да не е същото като това, което използвате __FUNCTION__ добиви.


0 за отговор № 4

Не знам защо искате да го направите, но се надявам, че това е за целта за отстраняване на грешки. Очевидно най-лесният път е да се премине __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;
}
}

Разбира се, това няма да ви даде правилния резултат в мулти-нишка, но вероятно ще решите, че използвате a thread_local const char * g_last_function_called = "" променлива.

Причината, поради която ми харесва този метод, е, че всичкокоето трябва да направите, за да го премахнете от проекта си, е просто просто "намиране и замяна" на 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 и основен