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

时间:2019-04-15 11:53:04

标签: c++

在以下代码中,我希望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); }"
}

4 个答案:

答案 0 :(得分:9)

C ++中没有真正的方式来进行这种反射(无论如何,在撰写本文时)。最好的办法是使用包装宏,该宏会捕获您传递的令牌序列,从中创建一个字符串,然后将其与一些更有用的数据一起传递给 real 函数。

#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 << " )"; 
}

运行上面的代码on wandbox,输出:

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

答案 1 :(得分:4)

使用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());
}

答案 2 :(得分:0)

在@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); });
}

答案 3 :(得分:-1)

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