2

I would like to share the contents of an array of doubles a of size k with one or more STL vectors v1, v2...vn.

The effect that I want from this shared storage is that if the underlying array gets modified the change can be observed from all the vectors that share its contents with the array.

I can do that by defining the vectors v1...vn as vectors of pointers

vector<double*> v1;

and copy the pointers a to a + k into this vector. However, I do not like that solution. I want the vectors to be a vector of doubles.

Given that you can extract the underlying pointer from a vector I am assuming one could initialize a vector with an array in such a way that the contents are shared. Would appreciate help about how to do this.

san
  • 4,144
  • 6
  • 32
  • 50
  • 1
    By "share" do you mean that the `v`'s have to has distinct identity because they will do separate duty somehow (maybe having other values in `[l > k]`? Is there some reason that you can't make `a` a vector and the `v` references too it? – dmckee --- ex-moderator kitten Sep 13 '11 at 23:31
  • 1
    Related and possibly duplicate: [Converting between C++ std::vector and C array without copying](http://stackoverflow.com/questions/1733143/converting-between-c-stdvector-and-c-array-without-copying), though the answer to this part of the question is in a comment to the accepted answer to that question. – James McNellis Sep 13 '11 at 23:33
  • @dmckee What I want is that if an element of the array is modified all the corresponding elements of the vectors would be modified too. – san Sep 13 '11 at 23:34
  • BTW--So far you have told us how you think the implementation ought to work, but not what you *want to do*. The motivation might let us suggest another approach. – dmckee --- ex-moderator kitten Sep 14 '11 at 00:13
  • @dmckee I have a working implementation of a class with such an aliased storage based on arrays. I was hoping that I could have another implementation where each object stored a reference to a vector (as opposed to an array). The original implementation's constructor takes an array as an input, I was trying to preserve the input signature for the vector based implementation. What I hoped to achieve with the vector implementation is the ability to reserve and resize and the ability to exchange data cheaply with swap. – san Sep 14 '11 at 02:42
  • @dmckee I do realize though, that even if it were possible to give a vector view of an array it would not have solved my original problem. – san Sep 14 '11 at 05:22

4 Answers4

2

Given that you can extract the underlying pointer from a vector I am assuming one could initialize a vector with an array in such a way that the contents are shared.

No, you can't do this. The Standard Library containers always manage their own memory.

Your best option is to create the std::vector<double> and then use it as an array where you need to do so (via &v[0], assuming the vector is non-empty).

If you just want to have the container interface, consider using std::array (or boost::array or std::tr1::array) or writing your own container interface to encapsulate the array.

James McNellis
  • 348,265
  • 75
  • 913
  • 977
  • 1
    I think I did not explain myself clearly enough. I want to go in the opposite direction. Not expose the view of an existing vector as an array, but give a vector view of an existing array. Thanks for the correction, what I ameant with extraction was returning `&v[0]` – san Sep 13 '11 at 23:36
  • 2
    Right. You can't do that. I'm saying that your best option is to try to reverse it so that the `vector` owns the data, and if that is not possible, to write your own container interface. – James McNellis Sep 13 '11 at 23:39
1

OK, Standard Library containers are both holders of information, and enumerators for those elements. That is, roughly any container can be used in almost any algorithm, and at least, you can go through them using begin() and end().

When you separate both (element holding and element enumeration), as in your case, you may consider boost.range. boost.range gives you a pair of iterators that delimit the extent to which algorithms will be applied, and you have the actual memory store in your array. This works mostly to read-access them, because normally, modifying the structure of the vector will invalidate the iterators. You can recreate them, though.

Diego Sevilla
  • 28,636
  • 4
  • 59
  • 87
  • This is not exactly what I needed here but upvoting for the information. I am sure I will find an use for it elsewhere. – san Sep 14 '11 at 02:45
1

This sounds to me like you want to alias the array with a vector. So logically you want a vector of references (which doesn't work for syntactical reasons). If you really really need this feature, you can write your own ref wrapper class, that behaves exactly like an actual C++ reference, so the users of your vn vectors wont be able to distinguish between vector<T> and vector<ref<T> > (e.g. with T = double). But internally, you could link the items in the vectors to the items in your "master" array.

But you should have darned good reasons to do this overhead circus :)

bitmask
  • 32,434
  • 14
  • 99
  • 159
0

To answer your question, as far as I know std::vector can not be given an already constructed array to use. I can not even think how that could be done since there are also the size/capacity related variables. You can possibly try to hack a way to do it using a custom allocator but I feel it will be ugly, error prone and not intuitive for future maintenance.

That said, if I may rephrase your words a bit, you are asking for multiple references to the same std::vector. I would either do just that or maybe consider using a shared_ptr to a vector.

pattakosn
  • 365
  • 4
  • 13