C++如何将非静态成员函数指针传入模板函数统计执行耗时
问题根因
非静态类成员函数调用时需要依赖类实例,std::invoke调用非静态成员函数的规则要求必须将类实例(或实例指针、智能指针)作为成员函数指针之后的第一个参数传递,同时成员函数指针必须显式使用&取地址,你当前的调用缺少类实例参数,且未对成员函数取地址,因此报错。
解决方案
方案1:仅调整调用方式(无需修改模板代码)
你的现有getExecutionTime模板已经使用了std::invoke和完美转发,本身就支持非静态成员函数、lambda、函数对象等所有可调用类型,仅需调整调用参数即可:
- 对非静态成员函数显式加
&取地址 - 在成员函数指针之后传入类实例参数
修改后的调用代码如下:
// 把原来报错的行改成下面的即可 << getExecutionTime(&Obj::testFunc, obj, uniform_dist(rng), i) << std::endl;
方案2:使用std::bind绑定实例(可选)
如果你希望保持和普通函数一致的调用形式,可以提前将成员函数和类实例绑定:
#include <functional> // 需要引入头文件 // 在main函数创建obj后添加绑定逻辑 auto boundTestFunc = std::bind(&Obj::testFunc, &obj, std::placeholders::_1, std::placeholders::_2); // 后续调用和普通函数完全一致 << getExecutionTime(boundTestFunc, uniform_dist(rng), i) << std::endl;
可选优化:让模板同时返回函数执行结果
如果你的场景需要同时拿到被调用函数的返回值,可以调整模板实现:
template<typename Function, typename... Args> auto getExecutionTime(Function&& function, Args&&... args) -> std::pair<double, std::invoke_result_t<Function, Args...>> { auto t1 = std::chrono::high_resolution_clock::now(); auto result = 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(), result}; }
如果被调用函数返回void,可以额外加一个偏特化版本处理即可,无相关需求可以不用调整原有模板。
内容的提问来源于stack exchange,提问作者pom_jam
相关产品推荐
相关产品推荐

