Dot-Net

將 std::vector<T> 轉換為 .NET List<U> 的最有效方法是什麼?

  • June 30, 2021

將 std::vector 轉換為 .NET 列表的最有效方法是什麼?

為了給出一些上下文,我用 C++/CLI 包裝了一個非託管 C++ 類。C++/CLI 類包含一個指向 C++ 類的指針,並且我為每個公共方法都有一個包裝器。

一種方法返回一個 std::vector,所以在我的包裝器中我將返回 .NET 類列表。IE

// unmanaged class
class A
{
   public:
       std::vector&lt;int&gt; runList();
}

// managed class
public ref class A
{
   public:
       // the below is obviously extremely inefficient
       List&lt;UInt32&gt; MethodA()
       {
           std::vector&lt;unsigned int&gt; runList = mpChannelNode-&gt;runList();
           std::vector&lt;unsigned int&gt;::iterator itr;

           List&lt;UInt32&gt; list = gcnew List&lt;UInt32&gt;();

           for (itr = runList.begin(); itr != runList.end(); itr++)
           {
               list.Add(*itr);
           }

           return list;
       }

   private:
       A* mpChannelNode;
}

我怎樣才能使它更有效率?隨意為 .NET 類推薦不同的返回類型。假設我只需要將該向量以任何形狀或形式有效地放入託管世界。

如果您真的很擔心,請改用無法驗證的程式碼:

List&lt;unsigned&gt;^ MethodA()
{
   std::vector&lt;unsigned&gt; const& runList = mpChannelNode-&gt;runList();
   array&lt;unsigned&gt;^ ret = gcnew array&lt;unsigned&gt;(runList.size());
   if (runList.size())
   {
       pin_ptr&lt;unsigned&gt; dest = &ret[0];
       std::memcpy(dest, &runList[0], runList.size() * sizeof(unsigned));
   }
   return gcnew List&lt;unsigned&gt;(ret);
}

也就是說,如果任何一種方式都有明顯的差異,我會感到驚訝……

我不熟悉 C++-CLI,但您可以做的一個小改進是從一開始就創建具有正確容量的列表。

List&lt;UInt32&gt; list = gcnew List&lt;UInt32&gt;(runList.size());

另一個改進是預先增加你的 C++ 迭代器而不是後增加它,因為目前你為每個立即丟棄的元素創建一個額外的對象。

引用自:https://stackoverflow.com/questions/6146701