如何在c++中传递非静态成员函数指针到模板函数?



我试图在头文件中创建一个函数模板,该模板接受通用函数指针和打包参数。函数模板将使用打包的参数调用接收到的函数指针。我的目标是计算并返回函数指针的执行时间。

#ifndef LOGTIME_HPP
#define LOGTIME_HPP
#include <chrono>
#include <ratio>
template<typename Function, typename... Args>
double getExecutionTime(Function&& function, Args&&... args) {
auto t1 = std::chrono::high_resolution_clock::now();
std::invoke(std::forward<Function>(function), std::forward<Args>(args)...);
auto t2 = std::chrono::high_resolution_clock::now();
std::chrono::duration<double, std::milli> ms = t2 - t1;
return ms.count();
}
#endif

这似乎只适用于不是classstruct的成员函数的函数指针。下面是一些使用函数模板的示例代码:

#include <iostream>
#include <thread>
#include <random>
#include "LogTime.hpp" // header including getExecutionTime()
class Obj
{
public:
int testFunc(int dur, int num) {
std::cout << "test" << num;
for (int i = 0; i < dur; i++) {
std::cout << ".";
std::this_thread::sleep_for(std::chrono::milliseconds(1));
}
return 2;
}
};
int testFunc(int dur, int num) {
std::cout << "test" << num;
for (int i = 0; i < dur; i++) {
std::cout << ".";
std::this_thread::sleep_for(std::chrono::milliseconds(1));
}
return 1;
}
int main()
{
std::random_device dev;
std::mt19937 rng(dev());
std::uniform_int_distribution<> uniform_dist(1, 100);
Obj obj = Obj();
for (int i = 0; i < 10; i++) {
int rand = uniform_dist(rng);
std::cout << "elapsed: "
// this works
<< getExecutionTime(testFunc, uniform_dist(rng), i) << std::endl;

// this doesn't work 
<< getExecutionTime(Obj::testFunc, uniform_dist(rng), i) << std::endl;
}
}

我的问题是Obj::testFunc失败。我知道如果Obj::testFunc是静态的,那么函数将执行得很好。我读到std::invoke可以通过传递类类型的实例来调用成员函数。但是,我不知道如何将其合并到函数模板中(我以前从未使用过模板)。

我很感激任何帮助或见解。

非静态成员函数有一个类类型的隐式形参作为函数的第一个形参,它是映射到this指针的对象。这意味着需要将类类型的对象作为成员函数指针(如

)之后的第一个参数传递。
<< getExecutionTime(&Obj::testFunc, obj, uniform_dist(rng), i) << std::endl;

或者您可以使用lambda代替,如

<< getExecutionTime([&](){ obj.testFunc(uniform_dist(rng), i); }) << std::endl;