| helios (10258) | |
| Ah, I see. I interpreted the T as referring to a type different from the vector's element type. | |
|
|
|
| ResidentBiscuit (2645) | |
|
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. | |
|
|
|
| cire (2347) | |||
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.
An exception should be thrown so the object is not constructed. | |||
|
|
|||
| ne555 (4383) | |||
|
Again, for exception safety, take a look at http://www.stroustrup.com/except.pdf it uses a vector implementation as example.
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)By the way, ¿why the `*(temp+i)' obfuscation? | |||
|
Last edited on
|
|||
| cire (2347) | ||||
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:
| ||||
|
|
||||
| L B (3806) | |
Doesn't throw; terminate the program right then and there, not rethrow?
| |
|
Last edited on
|
|
| cire (2347) | |
|
No, it re-throws the same exception that was caught. http://stackoverflow.com/questions/2474429/does-throw-inside-a-catch-ellipsis-rethrow-the-original-error | |
|
Last edited on
|
|
| Catfish3 (275) | |||||
| |||||
|
|
|||||
| xerzi (605) | |||
Don't really want to make a copy though, you want to move the resources if possible like the buffer for a string.
Didn't know move had an iterator overload :P. | |||
|
|
|||
| Catfish3 (275) | |
|
@ xerzi: what is the benefit of using std::move() instead of std::copy() in this case? | |
|
|
|
| ResidentBiscuit (2645) | ||||||
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.
I wanted to gain some speed over using indices.
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.
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:
| ||||||
|
Last edited on
|
||||||
| L B (3806) | |||||
| |||||
|
|
|||||
| xerzi (605) | ||||||
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.
There is no difference ... They do the same thing only that way is less readable.
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.
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.
| ||||||
|
Last edited on
|
||||||
| ne555 (4383) | |||
|
> I wanted to gain some speed over using indices. The problem is... you are using indexes. I suppose that you instead wanted
About your `operator[]' http://cplusplus.com/forum/lounge/91192/2/#msg490573 quite bothersome as the code is exactly the same. http://www.cplusplus.com/forum/general/40626/ which reminds me, you don't have iterators | |||
|
Last edited on
|
|||
| naraku9333 (1038) | |
|
@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? | |
|
|
|
| L B (3806) | |
| @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. | |
|
|
|
| xerzi (605) | |
|
^ what L B said You are not moving the array, you're moving the elements of the array: http://www.cplusplus.com/reference/algorithm/move/ | |
|
Last edited on
|
|
| naraku9333 (1038) | |
| OK I see now, my thinking was that std::move moved the pointer of the old buffer replacing the newer one. I didn't think it through enough. | |
|
|
|
| Catfish3 (275) | ||
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? | ||
|
|
||
| L B (3806) | |
| I don't think the goal is to use less memory at any given time, but rather to avoid the cost of copying data that could just be re-used. | |
|
|
|