在 C++ 中,我希望分配一个固定大小(但大小在运行时确定)的 std::vector,然后写入该向量中的元素。这是我正在使用的代码:
int b = 30;
const std::vector<int> test(b);
int &a = test[3];
但是,这给了我一个编译器(MSVC 2010 Pro)错误:
错误 C2440:“初始化”:无法从“const int”转换为“int &”。转换会失去限定符。
我对const的理解是它使类的所有成员变量都成为常量。例如,以下工作正常:
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]; // This is fine, as desired
test.resize(10); // Error here, as expected
因此, std::vector 似乎将容器的 const 性传播到向量的元素,这看起来很奇怪,因为如果我希望元素是 const 我会使用std::vector<const int>
。因此,这让我觉得这是 std::vector 的一个缺点。
无论如何,如何创建一个 std::vector ,其大小在构造后无法更改,但其元素可以写入?
如果不编写自己的包装类,这是不可能的。如果你想使用普通的std::vector
,你得靠自律,不使用成员函数insert()
, push_back()
or emplace_back()
,直接或间接(例如通过back_inserter
).
请注意,目前有一项提案动态数组 http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2013/n3532.html对于新的 C++14 标准:
[...]我们建议为数组定义一个新的工具,其中数组的数量
元素在构造时绑定。我们称这些为动态数组,
动态阵列。
该提案实际上附带了一个参考实现,您可以在自己的代码中使用它(确保更改namespace std
暂时换成别的东西)。
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 and destruct:
dynarray() = delete;
const dynarray operator=(const dynarray&) = delete;
explicit dynarray(size_type c)
: store( alloc( c ) ), count( c )
{ size_type i;
try {
for ( size_type i = 0; i < count; ++i )
new (store+i) T;
} catch ( ... ) {
for ( ; i > 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()
{ for ( size_type i = 0; i < 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
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)