转换std::vector<;T>;到.NET列表<;U>;?

转换std::vector<;T>;到.NET列表<;U>;?,.net,visual-c++,c++-cli,.net,Visual C++,C++ Cli,将std::vector转换为.NET列表的最有效方法是什么 为了给出一些上下文,我用C++/CLI包装了一个非托管C++类。C++/CLI类保存指向C++类的指针,并且我为每个公共方法都有一个包装器。 一个方法返回std::vector,因此在我的包装器中,我将返回.NET类列表。即 // unmanaged class class A { public: std::vector<int> runList(); } // managed class pub

将std::vector转换为.NET列表的最有效方法是什么

为了给出一些上下文,我用C++/CLI包装了一个非托管C++类。C++/CLI类保存指向C++类的指针,并且我为每个公共方法都有一个包装器。 一个方法返回std::vector,因此在我的包装器中,我将返回.NET类列表。即

// 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;
}
//非托管类
甲级
{
公众:
std::vector runList();
}
//管理类
公共参考A级
{
公众:
//下面的方法显然效率极低
列表方法a()
{
std::vector runList=mpChannelNode->runList();
std::vector::迭代器itr;
List List=gcnew List();
对于(itr=runList.begin();itr!=runList.end();itr++)
{
列表。添加(*itr);
}
退货清单;
}
私人:
A*节点;
}

我怎样才能提高效率?请随意为.NET类推荐不同的返回类型。让我们假设我只需要以任何形式有效地将该向量引入托管世界。

我不熟悉C++-CLI,但您可以做的一个小改进是从一开始就创建具有适当容量的列表

List<UInt32> list = gcnew List<UInt32>(runList.size());
List List=gcnewlist(runList.size());

另一个改进是预先增加C++迭代器,而不是增加它的增量,因为目前你为每个被丢弃的元素创建了一个额外的对象。

< P>考虑将向量直接转换成数组。在调整向量大小之前,以下选项将有效

载体vec(10); int*数组=&vec[0]

然后,您应该能够将其作为一个传递的数组来填充列表(我认为——VS不在机器上)

您还应该创建一个您预期需要的大小的列表——逐个添加会很慢。

如果您真的非常关心它,请使用无法验证的代码:

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);
}
List^MethodA()
{
std::vector const&runList=mpChannelNode->runList();
数组^ret=gcnew数组(runList.size());
if(runList.size())
{
引脚ptr dest=&ret[0];
std::memcpy(dest,&runList[0],runList.size()*sizeof(unsigned));
}
返回新列表(ret);
}

这就是说,如果两者之间存在明显的差异,我会感到惊讶…

如果您只是包装一个
向量
,为什么不实现
IList
,并将所有操作代理到
向量
?嗨,Gabe-您能把它写进一个答案吗?:)如果说
int*
以某种方式实现了
IEnumerable
,或者可以传递给
List
的构造函数,那么不,那是不正确的。@Seth:正确,不会,但是@Gabe的建议也不会,如果不冒多次封送的风险的话(这显然会比你已经拥有的更糟糕)。真的,如果你做出@Marcel建议的改进,你现在拥有的或多或少都是理想的(除非你想要惰性编组)。std::memcpy与使用InteropServices命名空间中的Marshal.Copy相比如何?Marshal.Copy是否会更安全、更快速?@Seth:
Marshal::Copy
是根据
memcpy
实现的,因此它不会比
memcpy
快,而且可能会稍微快一点(阅读:可能不明显)由于它执行边界检查,速度较慢。它唯一的真正优势是,您的函数不会在IL元数据中标记为
不安全
,因为您不需要
pin_ptr
,这可能会使使用其他.NET语言的类更容易。