gpt4 book ai didi

c++ - 创建一个固定大小的 std::vector 并写入元素

转载 作者:IT老高 更新时间:2023-10-28 23:15:11 25 4
gpt4 key购买 nike

在 C++ 中,我希望分配一个固定大小(但大小在运行时确定)std::vector,然后写入该 vector 中的元素。这是我正在使用的代码:

int b = 30;
const std::vector<int> test(b);
int &a = test[3];

但是,这给了我一个编译器(MSVC 2010 Pro)错误:

error C2440: 'initializing' : cannot convert from 'const int' to 'int &'. Conversion loses qualifiers.

我对 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-ness 传播到 vector 的元素,这似乎很奇怪,因为如果我希望元素为 const,我会使用 std::vector<const int> .因此,这让我觉得这是 std::vector 的一个缺点。

无论如何,我怎样才能创建一个std::vector,其大小在构造后无法更改,但其元素可以写入?

最佳答案

如果不编写自己的包装类,这是不可能的。如果你想使用一个普通的std::vector,你必须依靠自律,不使用成员函数insert()push_back() emplace_back(),直接或间接(例如通过 back_inserter)。

请注意,目前有 dynamic arrays 的提案。对于新的 C++14 标准:

[...] we propose to define a new facility for arrays where the number of elements is bound at construction. We call these dynamic arrays, dynarray.

该提案实际上附带了一个引用实现,您可以在自己的代码中使用它(请确保暂时将 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

关于c++ - 创建一个固定大小的 std::vector 并写入元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15832387/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com