【问题标题】:Conversion from C++ to C# - Iterator issue从 C++ 到 C# 的转换 - 迭代器问题
【发布时间】:2021-12-30 15:08:19
【问题描述】:

请帮忙。

我必须将一些旧的 C++ 代码转换为 C#,并且在迭代器转换时遇到问题。 这是 C++ 代码:

// list<int> myList
for(list<int>::iterator iter = myList.begin(); iter != myList.end() and not end;)
{
    int element = *it;
    //
    ... do something
    //                       
    iter++;
    if(not end)
    {
        myList.push_back(element);
        myList.pop_front();
    }
}

我尝试将其直接 1:1 转换为 C# ...

// List<int> myList;
foreach (int element in myList)
{
    //
    ... do something
    //                       
    if (!end)
    {
        myList.Add(element);
        myList.RemoveAt(0);
    }
}

...但是我得到了一个 InvalidOperationException,抱怨迭代器无法工作,因为列表是用Add/RemoveAt...修改的...

所以我的第二次尝试是不使用迭代器:

// List<int> myList;
for (int iter = 0; iter < myList.Count && !end;)
{
    int element = myList[it];
    //
    ... do something
    //                       
    iter++;
    if (!end)
    {
        myList.Add(element);
        myList.RemoveAt(0);
    }
}

但现在我不确定 C# 代码的行为是否与 C++ 代码完全相同? 当使用push_backpop_front 时,C++ 中的迭代器会发生什么?它会保持在同一个元素上吗? 还是我需要修改 C# 代码并在 Add/RemoveAt 旁边执行另一个 iter++

【问题讨论】:

  • 据我所知,C++ std::list 和 C# list 是完全不同的结构。所以不要期望行为相似。
  • 我没想到。这就是我问的原因 :) 但在这种情况下,唯一有趣的是:当使用 push_backpop_front 时,C++ 中的迭代器会发生什么?当我知道这一点后,我会在 C# 中相应地管理它。
  • 由于 iter 是 C# 代码中的索引,并且您删除了列表的第一个元素,您应该在 RemoveAt 调用之后有一个 --iter 以保持它引用相同元素。
  • 好点! C++代码中的迭代器在使用pop_front后是否也引用了同一个元素?
  • 如果您想要从 C++ 到 C# 的一对一转换,您应该使用 LinkedList&lt;int&gt; 而不是 List&lt;int&gt;LinkedList 与 C++ std::list 的数据结构差不多

标签: c# c++


【解决方案1】:

Queue 似乎可以满足您的需求。我可能误读了它,但我认为 C++ 示例在 end 设置为 true 之前不会退出,因为 myList.end() 在被推回时会继续设置一个元素。

Queue<int> intQueue = new Queue<int>(new int[]{1, 2, 3});
for(bool end = false; !end && intQueue.TryPeek(out int element);)
{
    //do stuff
    if(end) break;
    intQueue.Enqueue(intQueue.Dequeue());
}

【讨论】:

    【解决方案2】:

    如果您使用枚举器(通过 foreach 隐式或通过 GetEnumerator 显式),那么您将被限制为无法修改集合。此外,正如 ALX23z 所指出的,C# 中与 std::list 的等价物是 LinkedList,而不是 List:

            LinkedList<int> myList = new LinkedList<int>();
            myList.AddLast(1);
            myList.AddLast(2);
            myList.AddLast(3);
            bool end = false;
            for (int iter = 0; iter < myList.Count && !end; iter++)
            {
                int element = myList.ElementAt(iter);
    
                //
                //... do something
                //                       
    
                if (end)
                    break;
    
                myList.AddLast(element);
                myList.RemoveFirst();
            }
    

    【讨论】:

      猜你喜欢
      • 2011-02-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-22
      相关资源
      最近更新 更多