我正在尝试编写一个方法装饰器
timing
,我打算使用如下:
auto res = timing(my_func, arg1, arg2);
其中
res
包含 my_func(arg1, arg2)
的结果。
我的
timing
实现如下所示:
template <typename FunctionT, typename ...ArgT, typename ResultT>
ResultT timing(FunctionT fn, ArgT... args) {
// do something here
ResultT result = fn(args...);
// do something else here
return result;
}
但是,这不会编译,因为 G++ 无法扣除上述调用的
ResultT
,例如以下最小的不工作示例:
#include <iostream>
// put timing method here
float my_func(float f, float g) {
return f + g;
}
int main() {
auto res = timing(my_func, 0.f, 3.f);
std::cout << "Result is: " << res;
}
使用
g++ test.cpp
编译时会抛出以下编译器错误:
test.cpp: In function ‘int main()’:
test.cpp:19:22: error: no matching function for call to ‘timing(float (&)(float, float), float, float)’
19 | auto res = timing(my_func, 0.f, 3.f);
| ~~~~~~^~~~~~~~~~~~~~~~~~~
test.cpp:5:9: note: candidate: ‘template<class FunctionT, class ... ArgT, class ResultT> ResultT timing(FunctionT, ArgT ...)’
5 | ResultT timing(FunctionT fn, ArgT... args) {
| ^~~~~~
test.cpp:5:9: note: template argument deduction/substitution failed:
test.cpp:19:22: note: couldn’t deduce template parameter ‘ResultT’
19 | auto res = timing(my_func, 0.f, 3.f);
| ~~~~~~^~~~~~~~~~~~~~~~~~~
为什么g++不能推导出模板参数
ResultT
,难道不应该由函数给出my_func
吗?
此外,当我专门提供
ResultT
的值时,它会起作用:
template <typename ResultT, typename FunctionT, typename ...ArgT>
ResultT timing(FunctionT fn, ArgT... args) {
// as before
}
int main() {
auto res = timing<float>(my_func, 0.f, 3.f);
}
有没有一种方法可以在不明确提及函数返回值的情况下进行编译?事实上,我打算使用此方法的函数确实有相当冗长的类型定义。
您需要确保可以从传递的参数中推导出
ResultT
。一种方法如下所示:
template <typename ...ArgT, typename ResultT>
ResultT timing(ResultT (*fn)(ArgT...), ArgT... args) {
ResultT result = fn(args...);
return result;
}
int main() {
auto res = timing(my_func, 0.f, 3.f); //works now
std::cout << "Result is: " << res;
}