【问题标题】:Cannot deduce type of indirectly called template function无法推断间接调用模板函数的类型
【发布时间】: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&lt;type of f&gt;),但我没有找到如何做到这一点。我需要对代码进行哪些更改?

顺便说一句,如果有其他同样通用的设计方法,但可以避免模板参数推导问题,我有兴趣了解它们。

【问题讨论】:

  • helper 是一个函数模板。编译器应该在optimize(f, -2, helper) 中使用helper 的哪个特化?
  • 为什么助手是模板?它对 f 没有任何作用。如果有原因,那么您可能会像 optimize(f, -2, helper&lt;decltype(f)&gt;) 那样做。
  • @ScottHutchinson:你说得对,在这个例子中,模板参数没有被使用。这个想法是可能有几个助手(实际上是行搜索方法),它们都执行相同的任务,即最小化单个变量的函数fdecltype 实际上是我在不知不觉中寻找的东西。

标签: c++ function templates


【解决方案1】:

您可以为L 添加一个默认类型,其中包括F

template<typename F>
double helper(F f, double x) {
    return f(x);
}

template<typename F, typename L = double(*)(F, double)>  // <- here
double optimize(F f, double x, L line_search) {
    double y = line_search(f, x);
    return y;
}

当你这样做时,它会找到正确的模板实例化

double solution = optimize(f, -2, helper);   // helper is helper<decltype(f)>

如果helper是你经常使用的函数模板,可以设为默认:

template<typename F, typename L = double(*)(F, double)>
double optimize(F f, double x, L line_search = helper<F>) {  // <- here
    double y = line_search(f, x);
    return y;
}

这样就可以在不指定助手的情况下调用optimize

double solution = optimize(f, -2);   // helper<decltype(f)> is the default

【讨论】:

    猜你喜欢
    • 2011-02-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-04
    • 1970-01-01
    • 2022-08-03
    相关资源
    最近更新 更多