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