vector :: assign如何在C ++中工作?

时间:2017-03-08 01:15:35

标签: c++ vector stl

如果我有以下代码:

std::vector<char> myvector;
char myarr[10];
myvector.reserve(10);
myvector.assign(myarr, myarr + 3);

最后一行(assign)是否可以作为 memcpy(&amp; myvector [0],myarr,3)如果我不考虑更新成员变量或调整大小。

1 个答案:

答案 0 :(得分:2)

确定让我们这样做

根据定义:http://www.cplusplus.com/reference/cstring/memcpy/

  

复制存储块从该位置复制num字节的值   源指向源直接指向的内存块   目的地。

     

源和指向的对象的基础类型   目标指针与此函数无关;结果是   数据的二进制副本。

     

该函数不检查中的任何终止空字符   source - 它总是复制num字节。

     

为了避免溢出,两者都指向了数组的大小   目的地和源参数,至少应为num个字节,和   不应该重叠(对于重叠的内存块,memmove是更安全的   方法)。

现在为矢量:http://www.cplusplus.com/reference/vector/vector/

  

向量是表示可以更改的数组的序列容器   大小

     

就像数组一样,矢量使用连续的存储位置   元素,这意味着他们的元素也可以使用   定期指向其元素的指针的偏移量,同样有效   在数组中。但与数组不同,它们的大小可以动态变化,   他们的存储由容器自动处理。

让我们深入研究一些实现,你会看到assign就是一切,但类似于memcpy,即使你不考虑调整大小和成员变量更新......)

当然......与新要求的元素数相比,它执行的计数大于或小于元素的副本,但会进行内存重新分配,绑定和有效性检查等等。

Memcpy只复制一个字节块,很高兴。矢量复制全元素。

为了您的兴趣:

GCC接口

https://gcc.gnu.org/onlinedocs/gcc-4.6.3/libstdc++/api/a01115_source.html

template<typename _InputIterator>
  void
    assign(_InputIterator __first, _InputIterator __last)
    {
        __glibcxx_check_valid_range(__first, __last);
        **_Base::assign(__gnu_debug::__base(__first),
                      __gnu_debug::__base(__last));**
         this->_M_invalidate_all();
         _M_update_guaranteed_capacity();
    }

  void
    assign(size_type __n, const _Tp& __u)
    {
        _Base::assign(__n, __u);
        this->_M_invalidate_all();
        _M_update_guaranteed_capacity();
    }

#ifdef __GXX_EXPERIMENTAL_CXX0X__
  void
    assign(initializer_list<value_type> __l)
    {
        _Base::assign(__l);
        this->_M_invalidate_all();
        _M_update_guaranteed_capacity();
    }
#endif

_base ::分配

https://gcc.gnu.org/onlinedocs/libstdc++/libstdc++-html-USERS-3.4/stl__vector_8h-source.html

void
  assign(size_type __n, const value_type& __val)
  { _M_fill_assign(__n, __val); }


template<typename _InputIterator>
  void
    assign(_InputIterator __first, _InputIterator __last)
    {
        // Check whether it's an integral type.  If so, it's not an iterator.
        typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
        _M_assign_dispatch(__first, __last, _Integral());
    }

M - 实现(并非所有这些都是必需的)......

https://gcc.gnu.org/onlinedocs/gcc-4.6.3/libstdc++/api/a01117_source.html

template<typename _Tp, typename _Alloc>
  void
    vector<_Tp, _Alloc>::
       _M_fill_assign(size_t __n, const value_type& __val)
    {
        if (__n > capacity())
        {
            vector __tmp(__n, __val, _M_get_Tp_allocator());
            __tmp.swap(*this);
        }
        else if (__n > size())
        {
            std::fill(begin(), end(), __val);
            std::__uninitialized_fill_n_a(this->_M_impl._M_finish,
                                          __n - size(), __val,
                                          _M_get_Tp_allocator());
            this->_M_impl._M_finish += __n - size();
        }
        else
            _M_erase_at_end(std::fill_n(this->_M_impl._M_start, __n, __val));
        }
    }

还有更多......还有更多...