我正在C ++ 17中使用模板编写通用的branch and bound算法。
当我提供默认模板参数RealFun2 = RealFun1时,代码可以正常编译(并运行):
template <typename Repr, typename SplFun, typename Predicate,
typename RealFun1, typename RealFun2=RealFun1>
optional<Repr> branch_and_bound(Repr r0, SplFun split, Predicate goal,
RealFun1 F, RealFun2 lower_bound) {
optional<Repr> BEST;
float F_BEST = INFINITY;
stack<Repr> ACTIVE; ACTIVE.push(r0);
while(!ACTIVE.empty()) {
Repr r = ACTIVE.top(); ACTIVE.pop();
if(goal(r)) {
if(F(r) < F_BEST) {
BEST = r;
F_BEST = F(r);
}
}
else
for(Repr q: split(r))
if(lower_bound(q) < F_BEST)
ACTIVE.push(q);
}
return BEST;
}
struct knapsack { /* ... */ };
using Repr = pair<knapsack, vector<int>>;
bool goal(Repr r) { /* ... */ }
float F(Repr r) { /* ... */ }
vector<Repr> split(Repr r) { /* ... */ }
float lower_bound(Repr r) { /* ... */ }
int main() {
// ...
knapsack K(N, cap, weight, value);
Repr r0(K, vector<int>(N, 0));
optional<Repr> BEST = branch_and_bound(r0, split, goal, F, lower_bound);
// ...
}
但是,g ++(7.3.0)抱怨说,如果我不提供默认值,它就无法推断出模板参数RealFun2:
template <typename Repr, typename SplFun, typename Predicate,
typename RealFun1, typename RealFun2>
// rest of code is the same
KNAPBB.cpp:105:72: error: no matching function for call to ‘branch_and_bound(Repr&, std::vector<std::pair<knapsack, std::vector<int> > > (&)(Repr), bool (&)(Repr), float (&)(Repr), <unresolved overloaded function type>)’
optional<Repr> BEST = branch_and_bound(r0, split, goal, F, lower_bound);
BRABOUND.cpp:11:16: note: template argument deduction/substitution failed:
KNAPBB.cpp:105:72: note: couldn't deduce template parameter ‘RealFun2’
optional<Repr> BEST = branch_and_bound(r0, split, goal, F, lower_bound);
我不了解在什么情况下是否需要提供默认值。
答案 0 :(得分:2)
因此,在错误消息的第一部分
no matching function for call to ‘branch_and_bound(Repr&,
std::vector<std::pair<knapsack, std::vector<int> > > (&)(Repr), bool(&)(Repr), float (&)(Repr), <unresolved overloaded function type>)’
未解析的重载函数类型> 部分标记了传递lower_bound
的参数。这意味着有更多具有该名称的函数,编译器无法确定您的意思。
<algorithm>
标头中有std::lower_bound
个函数,这意味着您在某个地方有using namespace std;
。
现在很明显,当最后一个模板参数为默认值时,为什么它可以工作-编译器不必猜测类型。
答案 1 :(得分:1)
问题原来是函数定义x0
中的函数名称。不幸的是,float lower_bound(Repr)
与lower_bound
中标准库中的函数冲突。没有模板默认值,编译器将没有足够的信息来区分用户提供的功能和标准库。