How can I construct a std :: vector or boost :: array from a C array without copying?

Given a pointer to an array of char, is it possible to build a std :: vector or boost :: array from it and avoid copying memory?

Thanks in advance!

+3


source to share


2 answers


Since vectors have their own allocators and storage, there is no way (for constructing non-primitive elements from move_iterator

, a bit can help).

So, assuming this will be true for the existing store std::vector<char>&

, you will never succeed, even with custom allocators.


If you need a string, you can use boost::string_ref

(in utility/string_ref.hpp

).

Otherwise you can use 1-dimensional multi_array_ref

(from Boost Multi Array)

1. Using string_ref

This is definitely the easiest:

Live On Coliru

#include <boost/utility/string_ref.hpp>
#include <iostream>

using boost::string_ref;

int main() {
    char some_arr[] = "hello world";

    string_ref no_copy(some_arr);

    std::cout << no_copy;
}

      



2. multi_array_ref

This is more versatile and works "better" if you are not string-oriented.

Live On Coliru

#include <boost/multi_array/multi_array_ref.hpp>
#include <iostream>

using ref = boost::multi_array_ref<char, 1>;
using boost::extents;

int main() {
    char some_arr[] = "hello world";

    ref no_copy(some_arr, extents[sizeof(some_arr)]);

    std::cout.write(no_copy.data(), no_copy.num_elements());
}

      

Both examples print

hello world

      


ยน, specializing in std::allocator<char>

, too vicious to consider and possibly outright forbidden by the standard

+6


source


An alternative without using boost would be std :: reference_wrapper

#include <vector>
#include <iostream>
#include <functional>

using namespace std;

struct S
{
    S() : val(0) {}
    S(int val_) : val(val_) {}
    S(const S& other) : val(other.val) {
        cout << "copy" << endl;
    }

    int val;
};


int main()
{
    char a[] = "Hello";
    vector<reference_wrapper<char>> v(a, a+5);

    S vS[] = {S(1), S(2), S(3)};

    vector<S> v_copy(vS, vS + 3);
    vector<reference_wrapper<S>> v_nocopy(vS, vS+3);
}

      



By using struct S

you can see that objects are not copied to vector. So this should work well for char

.

+1


source







All Articles