std::array or std::vector from pointer

我的未来我决定 提交于 2020-07-10 07:17:17

问题


I have an array of data in a C++/CLI array that I can pass to a native function using pin_ptr<T>, no problem so far. Now, however, I need to pass the array on to a C++/STL function that expects a container such as std::array or std::vector.

The easy way of doing this (which I did first), is to copy element by element.

The second-easiest way is to call std::copy(), see the answer to this question: convert System::array to std::vector.

However, I want to skip the entire copying step and just use the pointer instead. Seeing as std::array requires a template argument to determine its length, I can't create one at runtime (but please do correct me if I'm wrong). Is there a way to create a vector or a different type of STL container, without unnecessary copying of data?


回答1:


No it's not possible to do without copying, not with the standard containers anyway.

If you're still okay with copying then you should look at the std::vector constructor because I think the easiest way would be to do e.g.

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

If you definitely want to avoid copying, then it's not really that hard to write a simple wrapper around the pointer, including simple iterators needed for iteration (the reason it has to be a standard container I guess).


Just for fun and because I had some time over, I created just such a wrapper. It includes indexing and iterators. No bounds-checking.

See https://gist.github.com/pileon/c21cfba496e6c352dd81

Example program using it:

#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';
    }
}

Expected output from the program:

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 



回答2:


Since std::array is just a wrapper you can cast a regular array to a pointer to a std::array. This isn't usable for other containers of course.

#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);
}



回答3:


Since C++20 there is a way to use c++ containers with managed arrays in c++/cli that avoids copying the data: std::span

In c++20 it's possible to use std::span to wrap a managed c++/cli array. Then it can be used with standard container algorithms.

Unfortunately, Microsoft doesn't support c++/cli beyond c++17. Consequently one must first pass the pointer and length to a function in a different source file that is compiled using c++latest while compiling the caller's source file using the earlier c++17/cli. Fortunately the ABIs are compatible. This is easily set up for each file in the properties page of Visual Studio 2019.

Here's some sample code that creates a small managed array<double> then calls a function that wraps the managed data with std::span then sorts with 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());
}


来源:https://stackoverflow.com/questions/33654056/stdarray-or-stdvector-from-pointer

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!