如何递归地从迭代器定义向量?递归调用编译失败求助
问题分析与解决方案
你的问题出在auto返回类型的递归推导循环上。让我拆解一下为什么非递归没问题,递归就编译失败:
当你注释掉递归调用auto vr = Foo(f,m);时,编译器可以直接从return v;语句推导出函数的返回类型是vector<T>,这完全没问题。但一旦加入递归调用,编译器在推导当前Foo的返回类型时,需要知道递归调用的Foo(f,m)的返回类型——可这个返回类型又依赖于当前函数的返回类型推导,形成了循环依赖,编译器没法完成这个推导过程,自然就报错了。
解决方案:显式指定返回类型
既然auto推导在这里卡壳了,我们直接把返回类型明确写出来就行。因为你的函数最终返回的是vector<T>,其中T是迭代器的value_type,所以可以把函数的返回类型从auto改成vector<typename iterator_traits<ForwardIterator>::value_type>:
修正后的代码:
#include <vector> #include <iterator> template<typename ForwardIterator> vector<typename iterator_traits<ForwardIterator>::value_type> Foo(ForwardIterator f, ForwardIterator l) { typedef typename iterator_traits<ForwardIterator>::value_type T; auto n = distance(f,l); vector<T> v(n); auto h = n /2; auto m = next(f,h); auto vr = Foo(f,m); // 现在递归调用可以正常编译了 return v; } int main() { vector<int> v = { 38, 27, 43, 3, 9, 82, 10 }; auto rv = Foo(v.begin(), v.end()); return 0; }
补充说明
如果你的编译器支持C20及以上,还有另一种方式:用decltype(auto)配合前置声明,但显式指定返回类型是最直接、兼容性最好的方案,毕竟C11及以上都支持这种写法。
本质上,auto返回类型的推导需要编译器能在不依赖递归调用的情况下确定返回类型,而递归场景下这个条件不满足,所以必须打破这个循环——显式指定返回类型就是最直接的破局方法。
内容的提问来源于stack exchange,提问作者Sabetay Toros
相关产品推荐
相关产品推荐

