指针的std :: array或std :: vector

时间:2015-11-11 15:35:20

标签: arrays vector stl c++-cli mixed-mode

我在C ++ / CLI数组中有一组数据,我可以使用pin_ptr<T>传递给本机函数,到目前为止没问题。但是,现在我需要将数组传递给C ++ / STL函数,该函数需要一个容器,例如std::arraystd::vector

这样做的简单方法(我先做过)是按元素复制。

第二种最简单的方法是致电std::copy(),查看此问题的答案:convert System::array to std::vector

但是,我想跳过整个复制步骤而只是使用指针。看作std::array需要一个模板参数来确定它的长度,我不能在运行时创建一个(但如果我错了,请纠正我)。有没有办法创建一个矢量或不同类型的STL容器,而不需要不必要的数据复制?

3 个答案:

答案 0 :(得分:1)

不能没有复制,不管标准容器是不是没有。

如果您仍然可以复制,那么您应该查看std::vector constructor因为我认为最简单的方法就是这样做。

std::vector<T>(your_pointer, your_pointer + number_of_elements)

如果你肯定想避免复制,那么在指针周围写一个简单的包装器并不是那么难,包括迭代所需的简单迭代器(我猜它必须是一个标准的容器)。

只是为了好玩,因为我有一段时间,我创造了这样一个包装。它包括索引和迭代器。没有边界检查。

请参阅https://gist.github.com/pileon/c21cfba496e6c352dd81

使用它的示例程序:

#include <iostream>
#include "pointer_container.h"

int main()
{
    int a[20];
    std::iota(a, a + 20, 0);  // Initialize array

    {
        std::cout << "From array    : ";
        for (const auto item : a)
        {
            std::cout << item << ' ';
        }
        std::cout << '\n';
    }

    pointer_container<int> c(a, 20);
    {
        std::cout << "From container: ";
        for (const auto item : c)
        {
            std::cout << item << ' ';
        }
        std::cout << '\n';
    }
}

该计划的预期成果:

From array    : 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 
From container: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 

答案 1 :(得分:1)

由于std :: array只是一个包装器,因此可以将常规数组转换为指向std :: array的指针。当然,这不适用于其他容器。

#include <array>
#include <iostream>

void test(std::array<int, 10>* pia)
{
    std::cout << (*pia)[0] << std::endl;
}


int main()
{
    int ix[10]{ 0 };
    test((std::array<int, 10> *) ix);
}

答案 2 :(得分:1)

从C ++ 20开始,有一种方法可以在c ++ / cli中使用带有托管数组的c ++容器,从而避免复制数据:std::span

在c ++ 20中,可以使用std::span来包装托管的c ++ / cli数组。然后可以与标准容器算法一起使用。

不幸的是,Microsoft不支持c ++ 17以外的c ++ / cli。因此,必须先将指针和长度传递给使用c ++ latest编译的另一个源文件中的函数,同时使用较早的c ++ 17 / cli编译调用方的源文件。幸运的是,ABI是兼容的。可以在Visual Studio 2019的属性页中为每个文件轻松设置此设置。

以下是一些示例代码,它们创建了一个小的托管的array<double>,然后调用了一个函数,该函数用std::span包装托管数据,然后使用std::sort进行排序

// file1.cpp compile with /cli
#include <iostream>
using namespace System;
void sortme(double *p, int len);

int main()
{
    array<double>^ v = gcnew array<double> {1.0, 3.0, 2.0, 4.0};
    pin_ptr<double> pin=&v[0];
    int len=v->Length;
    sortme(pin, len);
    for (int i = 0; i < len; i++)
        std::cout << v[i] << "\n";  // prints sorted array
 }

// file2.cpp compile with c++latest
#include <span>
#include <algorithm>
void sortme(double *p, int len)
{
    std::span data_clr(p, len);
    std::sort(data_clr.begin(), data_clr.end());
}