Henrik Goldman wrote:
Note that you could use a "static" instance of one.
That is really not a good idea in my case since the code is used among
different projects and modules. It only makes it harder to understand.
It doesn't really need to be static, a const global will do. It should
be initialised in one module though. Although globals are normally
evil, if it's const it is less evil.
const mytype zero_my_type = { 0, 0, 0, 0 }; // etc
then my_type_vec.resize( 50, zero_my_type );
If you prefer you can scope the instance and expose the function but
you really haven't gained a lot.
Beware, by the way, that &v[0] or &v.front() is undefined behaviour if
v is an empty vector, so you should check for this and probably return
a NULL pointer when that is the case.
This is not the case for me fortunatly. In those places where I need it it
has been resize()'d in the constructor prior to any use.
I have wrapper "buffer" classes that will wrap arrays or vectors and it
also has a begin() and end() which are guaranteed to be pointers. (I
have two such classes, one for const and one for non-const). buffer is
fairly trivial to write and looks something like this:
template < typename T >
class buffer
{
T * itsData;
size_t itsSize;
public:
buffer( T* d, size_t sz ) : itsData( d ), itsSize( sz ) {}
buffer( vector< T & vec )
: itsData( vec.empty() ? 0 : &vec[0] ),
itsSize( vec.size() )
{
}
buffer() : itsData( 0 ), itsSize( 0 )
{
}
buffer( T* first, T* last ) : itsData( first ), itsSize( last -
first )
{
}
T* begin() const { return itsData; }
T* end() const { return itsData + itsSize; }
bool empty() const { return itsSize == 0; }
size_t size() const { return itsSize; }
};
Define const_buffer exactly the same but with const T* pointers and
const std::vector<T& and add this constructor
const_buffer( const buffer<T& nc_buf ) : itsData( nc_buf.begin()
), itsSize( nc_buf.size() )
{
}
Note that these classes do not take ownership of the buffer so there is
no memory handling issue. You might be surprised that begin() and end()
are const methods even in buffer. They are because you cannot modify
the pointers themselves, only what they point to. The class is
non-mutable (cannot be changed) other than assigning it to another
instance. Note that its constructors that take one parameter are
purposely non-explicit.
Now with a vector that might be empty and passing it to a functino that
takes a pointer and size that might be empty you can always pass in
buffer( theVec ).begin() (or const_buffer( theVec ).begin() if
appropriate)