如何打印作为参数传递的函数的名称

How to print the name of function passed as an argument?

本文关键字:参数传递 函数 何打印 打印      更新时间:2023-10-16

在下面的代码中,我希望Benckmark打印传递到Benchmark的函子的名称。

#include<iostream>
using namespace std;
// You can only modify Benchmark
template<typename F>
void Benchmark(F f)
{
    f();
    // print the name to which f() refers.
 }
// A cannot be modified
void A(int x)
{
}
void main()
{
    int x = 1;
    Benchmark([&]() {A(x); }); // should only print "A" rather than "[&]() {A(x); }"
}

C++中没有办法进行这种反思(无论如何,在撰写本文时(。你能做的最好的事情是使用包装宏,它获取你传递的令牌序列,从中创建一个字符串,并将其与一些更有用的数据一起传递给真正的函数。

#define Benchmark(...) BenchmarkImpl(__VA_ARGS__, #__VA_ARGS__, __FILE__, __LINE__)
template<typename F>
void BenchmarkImpl(F f, char const* name, char const* file, unsigned long long line)
{
    f();
    std::cout << "ran " << name << "(" << file << ", line " << line << " )"; 
}

在魔杖盒上运行上面的代码,打印:

ran [&]() {A(); } (prog.cc, line 19 )

使用 MACRO,您可以执行一些操作:

template<typename F>
void Benchmark(const char* name, F f)
{
    std::cout << name << std::endl;
    f();
}
#define BENCHMARK(f) Benchmark(#f, [](){ f; })
void A()
{
    // 
}
int main()
{
    BENCHMARK(A());
}

在@TellStory的答案中添加修剪内容。

#include <regex>
#include <iostream>
using namespace std;
#define Benchmark(...) BenchmarkImpl(__VA_ARGS__, #__VA_ARGS__)
template<typename F>
void BenchmarkImpl(F f, char const* name)
{
    const string input = name;
    const regex regex("\{\s*(\w+)\s*\(");
    smatch match;
    string output = "defaultName";
    if (regex_search(input, match, regex))
        output = match.str(1);
    f();
    cout << "Function name: " << output << endl;
}
void Ab1(int x)
{
    //
}
int main()
{
    int x = 10;
    Benchmark([&]() {   Ab1   (x); });
}
C++没有

类型反射,但有一个解决方法。不优雅,但有效。

#include <iostream>
using namespace std;
typedef void (*FunctionType)();
template<typename F>
void Benchmark(F f)
{
    f();
}
#define BENCHMARKTEST(F, f) 
cout << "Benchmark test for:" << #f << endl; 
Benchmark<F>(f);
void funcToBeTest()
{
}
int main()
{
    BENCHMARKTEST(FunctionType, funcToBeTest);
    return 0;
}