是否有可能制作一个函数包装器来运行注入的代码并返回与注入的函数相同的数据
Is there a possibility to make a function wrapper that runs the injected code and returns the same data as the injected function?
我玩弄这个想法已经有一段时间了,但似乎无法理解它。
基本上,我想做的是创建一个通用的 Timer 类,该类对所有传递给它的函数进行计时。当多次调用同一函数时对其进行平均,因此它必须以某种方式存储它。因此,它应该使用函数名称来存储任务,并在任务多次发生时对其进行平均。
它应该是什么样子的伪代码。
Class FunctionTaks
{
std::string d_name;
double d_execution_time;
}
Class Timer
{
private:
std::vector<FunctionTask> d_tasks;
public:
template <typename Function, typename ReturnType>
ReturnType time(Function f)
{
// check if function f is timed for first time
// start timer
// run function f
auto r = f.invoke();
// stop timer
// store function name and time, average if more than once
// return whatever f should return
return r;
}
void report() const;
}
我真的不知道该怎么做,尤其是当函数 f 具有不同数量的参数时。
Timer t;
t.time(foo());
t.time(bar());
t.time(foo());
t.report();
我基本上有几个核心问题。
- 如何让函数包装器返回与注入的代码假定返回的相同类型。
- 如何获取正在注入的函数名称。
- 包装器不应受到传递给注入函数的参数的限制。如何赋予注入函数参数的自由。
另一方面,我并不真正关心参数和返回类型,包装器应该简单地按原样运行注入的函数并执行一些计时,然后返回注入的函数应该返回的任何内容。
C++11 但为什么是模板?您需要 lambda 表达式:
typedef void(*TimerFunction)();
void time(TimerFunction fun) {
// start timer
fun();
// stop timer
}
int fun1() { return 1; }
int fun2() { return 2; }
string fun3() { return string("Test"); }
main() {
int ret1, ret2;
string ret3;
t.time([&ret1]() { ret1 = fun1(); });
t.time([&ret2]() { ret2 = fun2(); });
t.time([&ret3]() { ret3 = fun3(); });
}
这就是概念。有关详细信息:C++ lambda 将捕获作为函数指针
使用 C++11,您可以使用变量模板参数:
class TimerFoo {
public:
template <class Foo, class... Args> TimerFoo(Foo foo, Args... args) {
// ... start timer
foo(args...);
// ... stop timer
}
};
并使用例如:
TimerFoo tf = TimerFoo(foo, 1, 2, 3);
当然,您需要TimerFoo中的一些字段来存储测量的时间...
编辑:
为了能够使用此方法返回函数的值,您可以将上面的代码更改为:
#include <iostream>
using namespace std;
class TimerFoo {
public:
template <class Foo, class... Args> auto run(Foo foo, Args... args) -> decltype(foo(args...)) {
// ... start timer
auto result = foo(args...);
// ... stop timer
return result;
}
};
int foo(int a, int b) {
return 2;
}
int main() {
TimerFoo tf;
cout << tf.run(foo, 1, 2) << endl; // output: 2
}
相关文章:
- 将具有固定签名的自定义函数名称注入 CRTP
- 如何在窗口中使用注入的 dll 中的参数调用函数
- 如何在不诉诸依赖注入的情况下模拟遗留函数?
- 现代编译器是否可以在使用依赖关系注入时取消虚拟化函数调用
- 使用参数调用远程进程中的函数(注入的 DLL)
- 班级名称注入和构造函数
- 检测是否已从注入的 dll 调用函数
- 类中的 C++ 注入函数
- 调用注入DLL中的函数
- C 对象组成,注入和复制构造函数
- C++ - DLL 注入和调用函数
- 从注入进程的 DLL 调用函数并更改指针函数的地址
- 依赖注入/继承设计模式的构造函数参数太多
- 为什么有些函数需要作为DLL文件注入才能工作
- 注入DLL的函数中出现访问冲突异常(5)
- C++中构造函数注入的高级配置
- 通过注入的 DLL 绕行成员函数
- 是否有可能制作一个函数包装器来运行注入的代码并返回与注入的函数相同的数据
- 使用注入的类名调用成员函数
- C++通过构造函数注入"策略"