Home > Enterprise >  Initialize std::vector with given array without std::allocator
Initialize std::vector with given array without std::allocator

Time:01-17

I am using an external library which provides a function with the following interface:

void foo(const std::vector<int>& data);

I am receiving a very large C-style array from another library which has already been allocated:

int* data = bar();

Is there any way for me to pass on data to foo without allocating and copying each element? data is very large and therefore I want to avoid a copy and allocation if possible.

I could have used allocators, but foo is not templated for an allocator, so I don't believe this is possible.

I understand I may be asking for magic, but if it is possible that would be great. Of course if foo rather took an std::span this would not be a problem.

Thanks!

Edit: Make ```foo`` take a const reference instead of just a reference.

CodePudding user response:

Is there any way for me to pass on data to foo without allocating and copying each element?

No, there's no way of avoiding it given the premise.

There are two alternative workarounds by changing the premise:

  • Change the other library to return a vector.
  • Change foo to not require a vector. As you point out, std::span would probably be a reasonable choice.

CodePudding user response:

Magic

This answer is a magic depented on implementation of compiler.

We can forcely access the contain of vector.

Take g as an example, it use 3 protected pointers, _M_start, _M_finish, and _M_end_of_storage to handle storage. So we can create a derived class that set/reset the pointers to retuen of bar() in ctor/dtor.

Example code for g :

static_assert(__GNUC__ == 7 && __GNUC_MINOR__ == 5 && __GNUC_PATCHLEVEL__ == 0);    
class Dmy: public std::vector<int>{
public:
    Dmy(int *b, int *e)
    {
        _M_impl._M_start = b;
        _M_impl._M_finish = e;
        _M_impl._M_end_of_storage = _M_impl._M_finish;
    }
    ~Dmy()
    {
        _M_impl._M_start = 0;
        _M_impl._M_finish = 0;
        _M_impl._M_end_of_storage = 0;
    }
};
foo(Dmy(data,end_of_data));
  •  Tags:  
  • Related