c++ - Create a fixed size std::vector and write to the elements -
in c++ wish allocate fixed-size (but size determined @ runtime) std::vector write elements in vector. code using:
int b = 30; const std::vector<int> test(b); int &a = test[3];
however, gives me compiler (msvc 2010 pro) error:
error c2440: 'initializing' : cannot convert 'const int' 'int &'. conversion loses qualifiers.
my understanding of const makes of member variables of class constant. example, following works fine:
class myvec { public: myvec(int num) : ptr_m(new int[num]) {}; ~myvec() { delete ptr_m; } void resize(int num) { delete ptr_m; ptr_m = new int[num]; } int & operator[] (int i) const { return ptr_m[i]; } int *ptr_m; }; const myvec test(30); int &a = test[3]; // fine, desired test.resize(10); // error here, expected
it therefore seem std::vector propagates const-ness of container elements of vector, seems odd because if had wanted elements const have used std::vector<const int>
. therefore strikes me shortcoming of std::vector.
in case, how can create std::vector size cannot changed after construction, elements can written to?
this not possible without writing own wrapper class. if want use plain std::vector
, have rely on self-discipline not using member functions insert()
, push_back()
or emplace_back()
, either directly or indirectly (e.g. via back_inserter
).
note there current proposal dynamic arrays new c++14 standard:
[...] propose define new facility arrays number of elements bound @ construction. call these dynamic arrays, dynarray.
the proposal comes reference implementation can use in own code (make sure change namespace std
else time being).
namespace std { template< class t > struct dynarray { // types: typedef t value_type; typedef t& reference; typedef const t& const_reference; typedef t* iterator; typedef const t* const_iterator; typedef std::reverse_iterator<iterator> reverse_iterator; typedef std::reverse_iterator<const_iterator> const_reverse_iterator; typedef size_t size_type; typedef ptrdiff_t difference_type; // fields: private: t* store; size_type count; // helper functions: void check(size_type n) { if ( n >= count ) throw out_of_range("dynarray"); } t* alloc(size_type n) { if ( n > std::numeric_limits<size_type>::max()/sizeof(t) ) throw std::bad_array_length(); return reinterpret_cast<t*>( new char[ n*sizeof(t) ] ); } public: // construct , destruct: dynarray() = delete; const dynarray operator=(const dynarray&) = delete; explicit dynarray(size_type c) : store( alloc( c ) ), count( c ) { size_type i; try { ( size_type = 0; < count; ++i ) new (store+i) t; } catch ( ... ) { ( ; > 0; --i ) (store+(i-1))->~t(); throw; } } dynarray(const dynarray& d) : store( alloc( d.count ) ), count( d.count ) { try { uninitialized_copy( d.begin(), d.end(), begin() ); } catch ( ... ) { delete store; throw; } } ~dynarray() { ( size_type = 0; < count; ++i ) (store+i)->~t(); delete[] store; } // iterators: iterator begin() { return store; } const_iterator begin() const { return store; } const_iterator cbegin() const { return store; } iterator end() { return store + count; } const_iterator end() const { return store + count; } const_iterator cend() const { return store + count; } reverse_iterator rbegin() { return reverse_iterator(end()); } const_reverse_iterator rbegin() const { return reverse_iterator(end()); } reverse_iterator rend() { return reverse_iterator(begin()); } const_reverse_iterator rend() const { return reverse_iterator(begin()); } // capacity: size_type size() const { return count; } size_type max_size() const { return count; } bool empty() const { return count == 0; } // element access: reference operator[](size_type n) { return store[n]; } const_reference operator[](size_type n) const { return store[n]; } reference front() { return store[0]; } const_reference front() const { return store[0]; } reference back() { return store[count-1]; } const_reference back() const { return store[count-1]; } const_reference at(size_type n) const { check(n); return store[n]; } reference at(size_type n) { check(n); return store[n]; } // data access: t* data() { return store; } const t* data() const { return store; } }; } // namespace std
Comments
Post a Comment