【发布时间】:2021-09-11 03:11:28
【问题描述】:
以下代码片段是应该成为优化算法的精简版:
template<typename F>
double helper(F f, double x)
{
return x;
}
template<typename F, typename L>
double optimize(F f, double x, L line_search)
{
double y = line_search(f, x);
return y;
}
int main()
{
auto f = [](double x){ return (x - 2) * (x - 2); };
double solution = optimize(f, -2, helper);
}
我使用模板参数 F 参数化了主函数 (optimize) 和辅助函数 (helper),用于他们试图最小化的函数。但是,代码无法编译;编译器无法确定line_search 的类型:
t04.cpp: In function ‘int main()’:
t04.cpp:17:45: error: no matching function for call to ‘optimize(main()::<lambda(double)>&, int, <unresolved overloaded function type>)’
double solution = optimize(f, -2, helper);
^
t04.cpp:8:8: note: candidate: template<class F, class L> double optimize(F, double, L)
double optimize(F f, double x, L line_search)
^~~~~~~~
t04.cpp:8:8: note: template argument deduction/substitution failed:
t04.cpp:17:45: note: couldn't deduce template parameter ‘L’
double solution = optimize(f, -2, helper);
(我使用的是 gcc v7.5.0,但我认为这并不重要。)我想我明白为什么编译器不知道 line_search 的类型(它不看内部 optimize看看line_search 是如何被调用的),但我不知道如何解释正确的类型应该是什么。我希望我可以说optimize(f, -2, helper<type of f>),但我没有找到如何做到这一点。我需要对代码进行哪些更改?
顺便说一句,如果有其他同样通用的设计方法,但可以避免模板参数推导问题,我有兴趣了解它们。
【问题讨论】:
-
helper是一个函数模板。编译器应该在optimize(f, -2, helper)中使用helper的哪个特化? -
为什么助手是模板?它对 f 没有任何作用。如果有原因,那么您可能会像
optimize(f, -2, helper<decltype(f)>)那样做。 -
@ScottHutchinson:你说得对,在这个例子中,模板参数没有被使用。这个想法是可能有几个助手(实际上是行搜索方法),它们都执行相同的任务,即最小化单个变量的函数
f。decltype实际上是我在不知不觉中寻找的东西。