创建一个固定大小的std :: vector并写入元素 [英] Create a fixed size std::vector and write to the elements

查看:120
本文介绍了创建一个固定大小的std :: vector并写入元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

In C++ I wish to allocate a fixed-size (but size determined at runtime) std::vector then write to the elements in this vector. This is the code I am using:

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

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

However, this gives me a compiler (MSVC 2010 Pro) error:


错误C2440:正在初始化:无法从 const int转换为 int&。转换失去了限定符。

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

我对const的理解是,它使类的所有成员变量保持不变。例如,以下方法可以正常工作:

My understanding of const is that it makes all of the member variables of a class constant. For example, the 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]; // This is fine, as desired
test.resize(10); // Error here, as expected

因此,似乎std :: vector传播了const-ness容器到向量的元素之间,这似乎很奇怪,因为如果我希望元素为const,我会使用 std :: vector< const int> 。因此,这让我感到震惊的是std :: vector的缺点。

It would therefore seem that std::vector propagates the const-ness of the container to the elements of the vector, which seems odd because if I had wanted the elements to be const I would have used std::vector<const int>. This therefore strikes me as a shortcoming of std::vector.

无论如何,我如何创建一个std :: vector,其大小在构造后不能更改,但是

In any case, how can I create a std::vector whose size cannot be changed after construction, but whose elements can be written to?

推荐答案

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

This is not possible without writing your own wrapper class. If you want to use a plain std::vector, you have to rely on self-discipline by not using the member functions insert(), push_back() or emplace_back(), either directly or indirectly (e.g. via a back_inserter).

请注意,目前有新C ++ 14标准的动态数组


[...]我们建议为数组定义一个新的功能,在构造时必须绑定
个元素的数量。我们称这些动态数组为
dynarray。

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

该建议实际上带有一个参考实现,您可以自己使用它代码(暂时将命名空间std 更改为其他名称)。

The proposal actually comes with a reference implementation that you can use in your own code (make sure to change namespace std into something else for the 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 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

这篇关于创建一个固定大小的std :: vector并写入元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆