-1

Is there a C++ (preferably C++11) standard-compliant idiom which I can employ to allow a std::vector<double> to borrow the contents of a double[] of known size?

I have a function (actually a functor masquerading as a callback from an optimiser) with prototype:

double MyFunctorClass::operator()(double s[]) const;

(MyFunctorClass also has m_size which reveals the number of elements of s).

I want to call a function that takes a const std::vector<double>& as an input.

One solution technique involves my creating a std::vector<double> member variable and somehow switching the double[] data into the data area of that std::vector, call the function, then switch it back to the caller. I'd rather not copy due to performance concerns: it is the objective function. Any ideas?

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
  • 3
    No, there's no such idiom. A vector owns its contents. – jrok Dec 17 '13 at 14:39
  • I don't quite understand. Do you want to be able to access the underlying `double` array of an `std::vector`? Is that what you want? – Shoe Dec 17 '13 at 14:41
  • The interfaces cannot be adapted directly, but you could use one consistently (prefer to actually manage `std::vector` as adapting from a `vector` object to call a function requiring a pointer is trivial, but not the other way around). The performance impact of copying the data the first time to the vector should be small (assuming that this is not a tight loop) as it can be a plain `memcpy` – David Rodríguez - dribeas Dec 17 '13 at 14:42
  • Almost. I want to be able to tell the std::vector to use the double[]. But, of course, I'll need to detach it before the function exits. – Bathsheba Dec 17 '13 at 14:42
  • @Bathsheba, you want to have an `std::vector` that is constructed using your array? – Shoe Dec 17 '13 at 14:44
  • possible duplicate of [Converting between C++ std::vector and C array without copying](http://stackoverflow.com/questions/1733143/converting-between-c-stdvector-and-c-array-without-copying) – shakurov Dec 17 '13 at 14:44
  • 1
    Is it possible to change the function that demands a `vector`? The idiom is for a function like that to be a template taking an iterator range. Otherwise, you might be able to do something with a custom allocator, but it won't be pretty. – Mike Seymour Dec 17 '13 at 14:50
  • This link might prove helpful if i understand correctly -> [std::copy, etc](http://www.cplusplus.com/reference/algorithm/copy/) – James Dec 17 '13 at 14:51
  • Not what you want, but the opposite: you can use pointers to elemnents in a C-style array just like iterators. You can use them in std algorithms, etc. – John Dibling Dec 17 '13 at 15:22

3 Answers3

7

No, you cannot do that.

std::vector allocates space for stored content on the heap (and owns it), so you cannot force it to use your own memory.

By 'use your own memory' I mean 'your own memory with valid content, which is preserved and never touched by the container unless you explicitly say so'. Of course, you can define your own memory allocation policy by overriding 'allocator' parameter, but that is not a solution in this case.

Mateusz Grzejek
  • 11,698
  • 3
  • 32
  • 49
  • 2
    Well, with custom allocator you could force it to use already allocated memory. But you can't force different semantics on it. – jrok Dec 17 '13 at 14:49
  • @jrok: That is a fair point, this is fairly simple to do in [BSL](https://github.com/bloomberg/bsl), where there is a fair amount of prebuilt allocator support. – David Rodríguez - dribeas Dec 17 '13 at 15:02
  • @DavidRodríguez-dribeas Btw, I must admit, that I'm highly unsatisfied in terms of memory model in C++ 11. Just as we need specialized containers, we also need specialized allocators for the most typical situations. – Mateusz Grzejek Dec 17 '13 at 15:10
  • 1
    @MateuszGrzejek: There have been a couple of proposals. Some of the changes in the allocators were pursued to model the BSL style of allocators, which were invalid in C++03, but are now legal in C++11. That was one step, as C++11 added stateful allocators and control of whether allocators are propagated or not. The next step is to allow for scoped allocators (also in C++11), and polymorphic allocators (currently proposed, not yet standarized), after that proposal for standard allocators will probably follow. Note that part of the problem (without polymorphic allocators) is that [...] – David Rodríguez - dribeas Dec 17 '13 at 19:33
  • 1
    [...] the mechanism used to acquire the memory is part of the type, and make interaction with other [non-generic] code hard. A `std::vector` cannot be passed to a function taking a `const std::vector`. – David Rodríguez - dribeas Dec 17 '13 at 19:34
4

Change you function to accept templated begin and end iterators

instead of void foo( std::vector<double> vd )

use template<typename Iter> void foo( Iter begin, Iter end )

This will let you pass in any standard container or pointers.

iterate like so:

while( begin!=end ) {
  /*const?*/ double& value = *begin;
  // whatever you were going to do
  ++begin;
}
KitsuneYMG
  • 12,753
  • 4
  • 37
  • 58
0

If the double[] you want to temporarily store into the vector has no particular allocation constraints, you can use a second std::vector<double> and use std::swap(vec1, vec2) for quick elements exchange. Then to obtain a double[] from any of the vectors just do &vec[0].

Notice that I don't think that swapping is guaranteed to preserve the addresses of the internal arrays (although I cannot think of any implementation that doesn't). Edit: it's actually guaranteed (see comments).

Matteo Italia
  • 123,740
  • 17
  • 206
  • 299
  • In fact, swapping IS guaranteed to preserve the addresses of the internal arrays: "All iterators, pointers and references referring to elements in both containers remain valid, and are now referring to the same elements they referred to before the call, but in the other container, where they now iterate". But i do not understand what is the purpose of the second vector. We want to avoid ANY copying, and simply 'swap a pointers', which is impossible. – Mateusz Grzejek Dec 17 '13 at 15:00
  • 1
    @MateuszGrzejek Swapping two vectors does *not* copy elements. It's exactly what it does, "swaps pointers". – jrok Dec 17 '13 at 15:02
  • Between two vectors, yes. By 'avoid any copying', I meant creating second vector. – Mateusz Grzejek Dec 17 '13 at 16:14