   auto_array_ptr/reading into a vector
  Why isn't there an auto_array_ptr in C++?Or, to put the question another way, how do I read binary data from a file into a vector?The reason these two questions seem related to me is because I've been writing a simple ZIP file reader (I'm basically a C programmer), and if I want to read binary data into a dynamic array I seem to have 3 choices: use C pointers and have an exception-safety nightmare, write my own auto_array_ptr or something like this:std::vector<char> data(size);input_stream.read(&data[0], size);Which I don't like for two reasons: first, I don't believe &data[0] is guaranteed to work on all implementations and second I think the std::vector constructor will initialize the array which is a waste of time.However, auto_array_ptr also isn't in boost which leads me to think that there is a really good way to do this or a really good reason why the boost people haven't put it in (I think it has been proposed).   
  Because there's std::vector, which is guaranteed to have continguous memory.std::ifstream input_stream("filename", std::ios_base::binary);std::vector<char> data((std::istreambuf_iterator<char>(input_stream)),    std::istreambuf_iterator<char>());;Quote:Original post by ZQJWhich I don't like for two reasons: first, I don't believe &data[0] is guaranteed to work on all implementationsAs long as the vector is not empty, yes it is guaranteed to work on all standards conforming implementations.Quote:and second I think the std::vector constructor will initialize the array which is a waste of time.Let me get this straight.  You're worried about the cost of default-initialising a vector when you're about to read into it from a file?  You do realise that file I/O is orders of magnitude slower than memory access, right?  That default initialisation is going to be something like 0.1% of the total time spent in that section of code.  Don't worry about it.Enigma   ;Quote:Original post by SiCraneBecause there's std::vector, which is guaranteed to have continguous memory.std::ifstream input_stream("filename", std::ios_base::binary);std::vector<char> data((std::istreambuf_iterator<char>(input_stream)),    std::istreambuf_iterator<char>());Thanks, but how do I read a set number of bytes into memory that way? (Ok, I could do the other way of course).Quote:Original post by EnigmaLet me get this straight. You're worried about the cost of default-initialising a vector when you're about to read into it from a file? You do realise that file I/O is orders of magnitude slower than memory access, right? That default initialisation is going to be something like 0.1% of the total time spent in that section of code. Don't worry about it.True, I just hate wasted program time in general :)   ;Quote:Original post by ZQJQuote:Original post by SiCraneBecause there's std::vector, which is guaranteed to have continguous memory.std::ifstream input_stream("filename", std::ios_base::binary);std::vector<char> data((std::istreambuf_iterator<char>(input_stream)),    std::istreambuf_iterator<char>());Thanks, but how do I read a set number of bytes into memory that way? (Ok, I could do the other way of course).One of many ways:template < typename value_t >class istreambuf_generator {    typedef value_t value_type;    typedef std::istreambuf_iterator< value_type > iterator_type;    typedef std::istream istream_type;    iterator_type i;public:    istreambuf_generator( istream_type & istream )   : i( istream )    {    }    value_type operator()( void ) {   assert( i != iterator_type() && "Tried to read past EOF" );   value_type value = *i;   ++i;   return value;    }};std::ifstream input_stream("filename", std::ios_base::binary);std::size_t size = ...;std::vector< char > data( size );std::generate( data.begin() , data.end() , istreambuf_generator< char >( input_stream ) );Quote:Quote:Original post by EnigmaLet me get this straight. You're worried about the cost of default-initialising a vector when you're about to read into it from a file? You do realise that file I/O is orders of magnitude slower than memory access, right? That default initialisation is going to be something like 0.1% of the total time spent in that section of code. Don't worry about it.True, I just hate wasted program time in general :)Of course, by worrying about trivial things like this, you waste your time, which in turn means you're unable to spend that time optimizing someplace it'll count - the end result being more wasted program time total than if you had properly allocated your time.If you're using Boost, there's also boost::scoped_array, which would be just like a theoretical std::auto_array[_ptr] minus the "Assignment-that-really-steals-ownership" and "Release" semantics.   ;Quote:Original post by SiCranestd::vector<char> data((std::istreambuf_iterator<char>(input_stream)),    std::istreambuf_iterator<char>());Why is the extra set of parentheses around the first constructor argument necessary? Without it, VC++ sees the line as a function prototype, rather than a variable declaration, but why does the extra set of brackets fix this?;Quote:Original post by bakery2k1Quote:Original post by SiCranestd::vector<char> data((std::istreambuf_iterator<char>(input_stream)),    std::istreambuf_iterator<char>());Why is the extra set of parentheses around the first constructor argument necessary? Without it, VC++ sees the line as a function prototype, rather than a variable declaration, but why does the extra set of brackets fix this?You are very correct about the line being a function prototype without the parentheses. It has to do with the "rule", if it looks like a function prototype, it is a function prototype. However, parentheses around the parameter type and name in a function declaration is illegal, so the only way to intepret that line would be a variable definition which passes values to the constructor.   ;  Excellent, thanks!   ;Quote:Original post by Brother BobQuote:Original post by bakery2k1Quote:Original post by SiCranestd::vector<char> data((std::istreambuf_iterator<char>(input_stream)),    std::istreambuf_iterator<char>());Why is the extra set of parentheses around the first constructor argument necessary? Without it, VC++ sees the line as a function prototype, rather than a variable declaration, but why does the extra set of brackets fix this?You are very correct about the line being a function prototype without the parentheses. It has to do with the "rule", if it looks like a function prototype, it is a function prototype. However, parentheses around the parameter type and name in a function declaration is illegal, so the only way to intepret that line would be a variable definition which passes values to the constructor.That's all true and all, but it's totally opaque unless you've gotten bitten by it before.As I recall, the Exceptional C++ article about it suggests the following instead:std::istreambuf_iterator<char> b(input_stream), e;std::vector<char> data(b,e);;Quote:Original post by me22That's all true and all, but it's totally opaque unless you've gotten bitten by it before.As I recall, the Exceptional C++ article about it suggests the following instead:std::istreambuf_iterator<char> b(input_stream), e;std::vector<char> data(b,e);I have made the mistake of making the function instead of the object quite a few times, and personally I think the cleanest solution is what SiCrane posted. Scott Meyers also suggests your appoach in Effective STL, but as I understand it mainly due to the fact that some old compilers just can't handle SiCrane's version, so it will be more portable.   