C++ 递归lambda和局部引用

C++ 递归lambda和局部引用,c++,recursion,c++14,C++,Recursion,C++14,我需要了解以下问题的根源: 我有一些代码必须执行数据的递归遍历。我决定尝试lambda表达式。下面是我的代码的完整示例(这不是我的实际代码,而是具有完全相同流的存根): struct项 { std::向量值; }; int main(int argc,char*argv[]) { 函数递归; 向量项; uint32_t大小[2]={7,2}; uint32_t计数器=0; 递归=[&项、递归、计数器和大小](uint32\u t c) { 如果(!items.size()) { items.em

我需要了解以下问题的根源: 我有一些代码必须执行数据的递归遍历。我决定尝试lambda表达式。下面是我的代码的完整示例(这不是我的实际代码,而是具有完全相同流的存根):

struct项
{
std::向量值;
};
int main(int argc,char*argv[])
{
函数递归;
向量项;
uint32_t大小[2]={7,2};
uint32_t计数器=0;
递归=[&项、递归、计数器和大小](uint32\u t c)
{
如果(!items.size())
{
items.emplace_back();
}
自动&currItem=items.back();
currItem.values.resize(大小[c++]);
对于(size_t i=0;i
上面的代码获取并清空
Item
的向量,在对函数的第一次调用中,它推送一个项,并对
Item::values
向量的成员执行一些操作。当
i
索引达到3时,我再次调用Recursive。它再次执行前一个调用所做的一切。但是,在第二个调用返回后,第一个循环终止!这是因为currItem引用不再指向其原始变量,而是指向某个未定义的对象。我想了解的是: 这是不是因为lambda的工作方式?但据我所知,这不应该是我实现的问题。我的第二个猜测是,一旦lambda进入其递归调用并通过调用
items.emplace_back()推送第二个成员,原始引用就会丢失
我不经常使用递归,以前也从未遇到过这种情况。

这与递归和lambdas无关

主要问题在于调用
emplace\u back
。如下列文件所述:

如果新的size()大于capacity(),则所有迭代器和引用(包括结束迭代器的过去部分)都将无效。否则,只有结束迭代器的过去部分无效

解决问题的一个方法是使用整数索引而不是迭代器


编辑:不仅迭代器无效,而且第一个元素(
items.begin()
)和结束元素(
items.back()
)的返回值)也无效


您正在使用
items.back()
函数获取
curroitem
变量的值。在第二次调用中调用
emplace\u back()
后,第一次调用的
curryItem
变量无效,因此循环无法正确继续。

这与递归或lambdas无关

主要问题在于调用
emplace\u back
。如下列文件所述:

如果新的size()大于capacity(),则所有迭代器和引用(包括结束迭代器的过去部分)都将无效。否则,只有结束迭代器的过去部分无效

解决问题的一个方法是使用整数索引而不是迭代器


编辑:不仅迭代器无效,而且第一个元素(
items.begin()
)和结束元素(
items.back()
)的返回值)也无效


您正在使用
items.back()
函数获取
curroitem
变量的值。在第二次调用中调用
emplace\u back()
后,第一次调用的
curroItem
变量无效,因此循环无法正确继续。

@AndyG correct。删除了C++11标记。即C++14在调用过程中(可能)更改项向量的大小。这可能会使它的所有引用无效-想想如果向量没有足够的空间保留会发生什么。@AndyG这是一个输入错误。这里仍然有一些问题
Recurse
Recursive
不是相同的标识符,并且不会出现在代码段的其他地方。我不确定为什么需要在这里递归,您可以只循环
大小
counter
Recursive
@Caleth的主体中未使用。首先,“Recurse”是一个拼写错误,这一点非常明显。第二,正如我在问题中所说,整个代码只是我在应用程序中所做工作的简化存根。虽然你说得对,我可以不用递归就完成它,但在我的实际情况中,这会使很多事情变得复杂。@AndyG correct。删除了C++11标记。这就是C++14。在调用过程中,你(可能)正在更改项向量的大小。这可能会使它的所有引用无效-想想如果向量没有足够的空间保留会发生什么。@AndyG这是一个输入错误。这里仍然有一些问题
Recurse
Recursive
不是相同的标识符,并且不会出现在代码段的其他地方。我不确定为什么需要在这里递归,您可以只循环
大小
counter
Recursive
@Caleth的主体中未使用。首先,“Recurse”是一个拼写错误,这一点非常明显。第二,正如我在问题中所说,整个代码只是我在应用程序中所做工作的简化存根。虽然你说得对,我可以不用递归就完成,但在我的实际情况中,这会使很多事情复杂化
获取可以在其他地方重新分配的最后一个元素。我没有使用迭代器。您能详细说明一下吗?为了澄清这一点,
auto&currItem=items.back()获取可以在其他地方重新分配的最后一个元素。我没有使用迭代器。您能详细说明吗?
  struct Item
  {
     std::vector<float> values;
  };
 int main(int argc, char* argv[])
 {
  std::function<void(uint32_t)> Recursive ;
  std::vector<Item> items;
  uint32_t sizes[2] = {7,2};
  uint32_t counter = 0;

  Recursive = [&items,&Recurse,&counter,&sizes](uint32_t c) 
  {
     if (!items.size())
     {
         items.emplace_back();
     }

     auto &currItem = items.back();
     currItem.values.resize(sizes[c++]);

     for (size_t i = 0; i <  currItem.values.size(); i++)
     {
         currItem.values[i]+=5;
         if (i == 3)
         {
             items.emplace_back();
              Recursive (c);
              printf("end\n");
         }
         printf("end\n");
     }
};
 Recursive (counter);
  return 0;
}