将std :: vector转换为.NET List的最有效方法是什么?
为了给出一些上下文,我用C ++ / CLI包装一个非托管的C ++类。 C ++ / CLI类包含一个指向C ++类的指针,我有一个每个公共方法的包装器。
一个方法返回一个std :: vector,所以在我的包装器中我将返回.NET类List。即。
// unmanaged class
class A
{
public:
std::vector<int> runList();
}
// managed class
public ref class A
{
public:
// the below is obviously extremely inefficient
List<UInt32> MethodA()
{
std::vector<unsigned int> runList = mpChannelNode->runList();
std::vector<unsigned int>::iterator itr;
List<UInt32> list = gcnew List<UInt32>();
for (itr = runList.begin(); itr != runList.end(); itr++)
{
list.Add(*itr);
}
return list;
}
private:
A* mpChannelNode;
}
如何才能提高效率?随意为.NET类推荐不同的返回类型。让我们假设我只需要以任何形式或形式有效地将该向量导入托管世界。
答案 0 :(得分:8)
如果您真的关注它,请使用无法验证的代码:
List<unsigned>^ MethodA()
{
std::vector<unsigned> const& runList = mpChannelNode->runList();
array<unsigned>^ ret = gcnew array<unsigned>(runList.size());
if (runList.size())
{
pin_ptr<unsigned> dest = &ret[0];
std::memcpy(dest, &runList[0], runList.size() * sizeof(unsigned));
}
return gcnew List<unsigned>(ret);
}
那就是说,如果两种方式之间存在显着差异,我会感到惊讶......
答案 1 :(得分:3)
我不熟悉C ++ - CLI,但您可以做的一个小改进是从头开始创建具有正确容量的列表。
List<UInt32> list = gcnew List<UInt32>(runList.size());
另一个改进是预先递增C ++迭代器而不是后递增它,因为当前你为立即丢弃的每个元素创建了一个额外的对象。
答案 2 :(得分:1)
考虑将矢量直接转换为数组..以下内容将起作用并且有效,直到您调整矢量大小。
vector vec(10); int * array =&amp; vec [0];
然后,您应该能够将(我认为 - VS不在机器上)作为传递的数组来填充您的列表。
您还应该创建一个您希望需要的大小的列表 - 逐个添加将会很慢。