
Le 18/10/11 19:44, Andrew Hundt a écrit :
On Sat, Oct 15, 2011 at 5:16 PM, Nathan Ridge<zeratul976@hotmail.com> wrote:
After reading this thread again, it seems to me that the reason we can't reach an agreement is that different people are proposing two fundamentally different ways of using static_vector:
1) As a variant of [std|boost]::array where not all the elements are constructed/used at the same time, and which keeps track of how many elements are currently in use.
2) As a variant of std::vector which keeps its memory on the stack, and which is used, literally, as a drop-in replacement for std::vector, in the sense that the developer was using std::vector, but then identified that in non-exceptional situations the actual number of elements used is below a certain threshold, and the program could use the optimization of not allocating memory dynamically.
Nate seems to have provided the best analysis of the situation that I have seen in the thread.
But isn't use-case 2 much better served by a vector that degrades gracefully by falling back to using the heap? I just can't see how throwing serves anyone's purpose well. As Dave Abrahams suggests, I agree that the best behavior for case (2) is falling back to the heap after exhausting the buffer, which conveniently fits the functionality provided by AutoBuffer. Therefore, I think StaticVector should focus on use case (1). +1
I'll probably attempt to make StaticVector fulfill use case (1) with bounds checking performed using assert, in a way that makes it viable for use internally within AutoBuffer as well if the writer of that library desired to. The way I see things, if I implement StaticVector using assert, someone can inherit from my class and add exceptions if desired. I may be mistaken, but one could not do the same the other way around without any sacrifice, since some implementations of exceptions incur performance penalties. I don't see the advantage to use internally AutoBuffer here, but maybe I'm missing something evident.
As for check/unchecked bounds, I'll start with push_back being checked, and provide unchecked_push_back + unchecked_insert. I know it is less popular than a policy based implementation but I feel like there will be reduced overhead for compiler implementations with less effective optimizations, though this is based only on others' comments earlier on in the thread. Since this is (for me at least) designed to also be useful for embedded applications which may have stricter requirements, I find this to be a sensible choice. I will add that the push_back is checked only in debug mode as it will use assert. Then the unchecked version lost its utility on release mode. Please rip my choices apart for me, so I can correct them now before I write more code :-)
I have one additional question regarding the size. It was requested that I use boost::uint_value_t<N>::least, but I am concerned this would inhibit uses where one inherits from StaticVector to add functionality such as what is found in AutoBuffer. Should I stick to std::size_t, boost::uint_value_t<N>::least, or allow the size type to be set with a template parameter?
You can always add a size_type template parameter that is defaulted to boost::uint_value_t<N>::least. Best, Vicente