我在C ++ / CLI数组中有一组数据,我可以使用pin_ptr<T>
传递给本机函数,到目前为止没问题。但是,现在我需要将数组传递给C ++ / STL函数,该函数需要一个容器,例如std::array
或std::vector
。
这样做的简单方法(我先做过)是按元素复制。
第二种最简单的方法是致电std::copy()
,查看此问题的答案:convert System::array to std::vector。
但是,我想跳过整个复制步骤而只是使用指针。看作std::array
需要一个模板参数来确定它的长度,我不能在运行时创建一个(但如果我错了,请纠正我)。有没有办法创建一个矢量或不同类型的STL容器,而不需要不必要的数据复制?
答案 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());
}