7
vector<int> vec;
boost::scoped_array<int> scpaInts;

scpaInts.reset(new int[10]);

for (int i=0; i<10; i++)
    scpaInts[i] = i*2;

vec.assign(&scpaInts[0], &scpaInts[9]+1);      // => method one
vec.assign(scpaInts.get(), scpaInts.get()+10); // => method two

Question 1> I have figured out two methods. But I am not sure whether they are correct or there is a better way to do this.

Question 2> Is it true that we cannot get the valid length from boost::scoped_array?

Thank you

PiotrNycz
  • 23,099
  • 7
  • 66
  • 112
q0987
  • 34,938
  • 69
  • 242
  • 387

5 Answers5

3

Question 1: both methods are ok. A pointer to an element of an array can play a role of a random-access iterator. This one is fine as well

vec.assign(&scpaInts[0], &scpaInts[10]);

Question 2: That is true for the same reason that you can't get the length of an C-style array passed to a function.

Andriy
  • 8,486
  • 3
  • 27
  • 51
  • Why the above the code `scpaInts[10]` is legal? It tries to access an out-of-boundary element? – q0987 Oct 26 '12 at 14:55
  • 2
    @q0987: http://stackoverflow.com/q/7346634/560648 http://stackoverflow.com/q/988158/560648 – Lightness Races in Orbit Oct 26 '12 at 14:57
  • @q0987,@Lightness Races in Orbit: [Take the address of a one-past-the-end array element via subscript: legal by the C++ Standard or not?](http://stackoverflow.com/questions/988158/take-the-address-of-a-one-past-the-end-array-element-via-subscript-legal-by-the) – Andriy Oct 26 '12 at 15:03
  • Summary of all that stuff: The C99 standard says that `&*` is treated as a no-op, so for a pointer `ptr`, `&ptr[10]` is equivalent to `ptr+10`, which is legal. The C++ standard doesn't explicitly say any such thing. Some people argue that it "should" be OK anyway, i.e. that you can apply `&` to an lvalue and since no lvalue-to-rvalue conversion is performed on the lvalue, it doesn't have to be an accessible object (you're allowed to have an off-the-end pointer but not access `scpaInts[10]`). – Steve Jessop Oct 26 '12 at 15:30
1

Both are ok. But the second one is more clear for me. boost::scoped_array works as simple arrays and you cant now the size of data. To copy it to vector you have to know it size. Here is link about scoped_array iterators and size.

Denis Ermolin
  • 5,530
  • 6
  • 27
  • 44
1

I'd select method 2:

vec.assign(scpaInts.get(), scpaInts.get()+10); // => method two

Like for ordinary dynamic array:

int * a = new int[10];
...
vec.assign(a, a+10); // => method two

Of course method 1 works too, like for example with dynamic array:

vec.assign(&a[0], &a[9]+1); // => method one

As you can see - the method 2 just looks simpler, thus better.


And, no, there is no size() method in scoped array.

PiotrNycz
  • 23,099
  • 7
  • 66
  • 112
1

Question 1: Both methods are correct.

Question 2: Correct, its just a container similar to std::scoped_ptr, which makes sure that the pointer passed (which was manually created using operator new[]) will be deleted using operator delete []. It doesn't hold any information about the size of the array.

Stacker
  • 1,080
  • 14
  • 20
1

Both methods seem correct to me, but the second is definitely clearer since you aren't splitting the offset into 9 and 1 components. There are also two other options:

vec.assign(&scpaInts[0], &scpaInts[0] + 10);

Or don't create the vector before you need it (best of all the options):

vector<int> vec(scpaInts.get(), scpaInts.get() + 10);
Mark B
  • 95,107
  • 10
  • 109
  • 188