D.p*_*.pz 5 c++ variadic-templates c++11 trailing-return-type
我正在使用 c++11 可变参数模板,但是编译器抱怨模板实例化深度超过 900 的最大值,代码如下所示:
template<typename F1, typename F2>
composed<F1, F2> compose(F1 f1, F2 f2) {
return composed<F1, F2>(f1, f2);
}
template<typename F1, typename F2, typename... Fs>
auto compose(F1 f1, F2 f2, Fs... fs) ->decltype(compose(compose(f1, f2), fs...)) {
return compose(compose(f1, f2), fs...);
}
Run Code Online (Sandbox Code Playgroud)
我正在使用这个模板,如:
auto composed_func = compose(f1, f2, f3, f4);
Run Code Online (Sandbox Code Playgroud)
但是,如果我将可变参数模板定义更改为:
template<typename F1, typename F2, typename F3, typename... Fs>
auto compose(F1 f1, F2 f2, F3 f3, Fs... fs) ->decltype(compose(compose(f1, f2), f3, fs...)) {
return compose(compose(f1, f2), f3, fs...);
}
Run Code Online (Sandbox Code Playgroud)
它会正常工作。我不清楚为什么会这样。在我看来,上面的用法看起来也有效,因为它仍然递归地减少调用 compose 的 args。
你可以用以下方法修复它:
template<typename F1, typename F2>
composed<F1, F2> compose(F1 f1, F2 f2) {
return composed<F1, F2>(f1, f2);
}
template<typename F1, typename F2, typename... Fs>
auto compose(F1 f1, F2 f2, Fs... fs)
->decltype(compose(::compose(f1, f2), fs...))
{
return compose(compose(f1, f2), fs...);
}
Run Code Online (Sandbox Code Playgroud)
不合格的名称可以通过 ADL 找到,并且名称在实例化时进行搜索。
因此,通过不合格的查找,我们首先生成候选者(即使它们不是更好的匹配)
compose(f, g)可:
template<typename F1, typename F2> composetemplate<typename F1, typename F2, typename...Fs> compose。(带FS空包)对于后一种情况,我们必须decltype(compose(compose(f, g)))再次解决compose(f, g)-> 无限递归。
另一方面,限定名称会立即搜索,并且只能找到完全声明的函数(因此不能找到其本身,因为尾随返回类型是声明的一部分)。因此::compose避免将自己视为重载的候选者。
| 归档时间: |
|
| 查看次数: |
1218 次 |
| 最近记录: |