Fixed some of the issues that have been talked about. Still no copy control, and still can't be used with objects with no default-constructor. Working on that currently. Let me know what you think so far: https://sourceforge.net/projects/datastructs/
I wasn't sure if I should throw exceptions to the user, or handle them at this level. Currently I'm catching, but not really doing anything. One question, if the allocation in the constructor fails, what will happen to the object?
I have a few commented questions throughout this, if you don't mind checking out for me.
I wasn't sure if I should throw exceptions to the user, or handle them at this level.
Throw them. Exception handling strategies don't belong in general library code, and seeing as you don't have a strategy for handling them.. definitely throw them.
One question, if the allocation in the constructor fails, what will happen to the object?
An exception should be thrown so the object is not constructed.
Lines (a) and (b) may thrown an exception.
If (b) also throws `bad_alloc' you may not be able to tell which one are you catching.
For (b) you need to deallocate the buffer, and destroy all the objects that were `created'.
Edit: as you are not using placement new, all the objects are already constructed.
I suppose that you could simply delete[] temp which will release everything properly. (you'll need to increase `temp' scope)
For (b) you need to deallocate the buffer, and destroy all the objects that were `created'.
Edit: as you are not using placement new, all the objects are already constructed.
I suppose that you could simply delete[] temp which will release everything properly. (you'll need to increase `temp' scope)
You'll also need to increase the range of exceptions you catch, as you can't know what exceptions may be thrown by the contained type during construction. Something like:
Throwing the exceptions makes much more sense, you're right. I have like no experience actually working with it though, so if I throw an exception out of the catch block like cire has shown above, I'm assuming the exception gets thrown to the user of the class? I read somewhere that it'll just get thrown into the next scope, but I don't feel like that's true.
By the way, ¿why the `*(temp+i)' obfuscation?
I wanted to gain some speed over using indices.
Lines (a) and (b) may thrown an exception.
If (b) also throws `bad_alloc' you may not be able to tell which one are you catching.
That's a good point. But would it matter? Either way it would lead to an inconsistent state. And I think this might get resolved when I finish writing my allocator class and use that.
what is the benefit of using std::move() instead of std::copy() in this case?
I second this. And also, are either of them going to be faster than direct pointer usage, like I'm doing right now?
EDIT:
Also, what is the point of this? I pulled it out of a book, and I don't understand why I need both:
I read somewhere that it'll just get thrown into the next scope, but I don't feel like that's true.
Hold on...are you saying you don't understand what a call stack is?
ResidentBiscuit wrote:
I don't understand why I need both
You need the non-const version so elements can be modified from outside the vector, and you need the const version to be able to access elements from a const perspective of the vector.
You are creating a copy then destroying the source, why wouldn't you try and save those resources ? If you have a vector of std::string you'll be reallocating and copying their buffers. With std::move you'd only be transferring the pointer, so no allocating and copying of the buffers.
I wanted to gain some speed over using indices.
There is no difference ... They do the same thing only that way is less readable.
are either of them going to be faster than direct pointer usage
It's just a way to keep your code clean and readable as well as not having a for loop everywhere doing the same thing.
what is the point of this? I pulled it out of a book, and I don't understand why I need both
It's for when the object is const, it'll use the second operator (the one with const appended to it) so that a const element is returned as well so that the values can't be modified to maintain the const of the vector.
@xerzi
I'm not particularly experienced with move semantics (just recently picked up a book on C++11) but wouldn't using std::move there be an issue since the buffers are different sizes?
@naraku: If that were so, then it would also be an issue with std::copy, and with the for loop, and with any other method of doing it you could think of.
With std::move you'd only be transferring the pointer, so no allocating and copying of the buffers.
I think what you mean is that std::copy() would use copy operator= while std::move() would use move operator=, possibly resulting in lower memory usage while transferring the data?
Apart from that, wouldn't the overall memory usage be the same?