• c++11 动态内存管理 -未初始化存储


    定义于头文件 

    将范围内的对象复制到未初始化的内存区域

    std::uninitialized_copy

    template< class InputIt, class ForwardIt >
    ForwardIt uninitialized_copy( InputIt first, InputIt last, ForwardIt d_first );

    (1)

    template< class ExecutionPolicy, class InputIt, class ForwardIt >
    ForwardIt uninitialized_copy( ExecutionPolicy&& policy, InputIt first, InputIt last, ForwardIt d_first );

    (2)(C++17 起)

    1) 复制来自范围 [first, last) 的元素到始于 d_first 的未初始化内存,如同用

    for (; first != last; ++d_first, (void) ++first)
       ::new (static_cast(std::addressof(*d_first)))
          typename std::iterator_traits::value_type(*first);

    若初始化中抛异常,则以未指定顺序销毁已构造的对象。

    2) 同 (1) ,但按照 policy 执行。此重载仅若 std::is_execution_policy_v> 为 true 才参与重载决议。

    参数

    first, last-要复制的元素范围
    d_first-目标范围的起始
    policy-所用的执行策略。细节见执行策略。
    类型要求
    - InputIt 必须满足遗留输入迭代器 (LegacyInputIterator) 的要求。
    - ForwardIt 必须满足遗留向前迭代器 (LegacyForwardIterator) 的要求。
    - 通过ForwardIt 合法实例的自增、赋值、比较或间接均不可抛异常。

    返回值

    指向最后复制的元素后一元素的迭代器。

    复杂度

    firstlast 间的距离成线性

    异常

    拥有名为 ExecutionPolicy 的模板形参的重载按下列方式报告错误:

    • 若作为算法一部分调用的函数的执行抛出异常,且 ExecutionPolicy 为标准策略之一,则调用 std::terminate 。对于任何其他 ExecutionPolicy ,行为是实现定义的。
    • 若算法无法分配内存,则抛出 std::bad_alloc 。

    可能的实现

    1. template<class InputIt, class ForwardIt>
    2. ForwardIt uninitialized_copy(InputIt first, InputIt last, ForwardIt d_first)
    3. {
    4. typedef typename std::iterator_traits<ForwardIt>::value_type Value;
    5. ForwardIt current = d_first;
    6. try {
    7. for (; first != last; ++first, (void) ++current) {
    8. ::new (static_cast<void*>(std::addressof(*current))) Value(*first);
    9. }
    10. return current;
    11. } catch (...) {
    12. for (; d_first != current; ++d_first) {
    13. d_first->~Value();
    14. }
    15. throw;
    16. }
    17. }

     调用示例

    1. #include <iostream>
    2. #include <vector>
    3. struct Foo
    4. {
    5. int N;
    6. Foo() {}
    7. explicit Foo(int n): N(n)
    8. {
    9. std::cout << "Foo(n)" << std::endl;
    10. }
    11. Foo(const Foo & o)
    12. {
    13. std::cout << "Foo(const Foo & o)" << std::endl;
    14. this->N = o.N;
    15. }
    16. Foo & operator =(const Foo &o)
    17. {
    18. std::cout << "operator =" << std::endl;
    19. this->N = o.N;
    20. return *this;
    21. }
    22. };
    23. int main()
    24. {
    25. std::vector<Foo> from_vector{Foo(1), Foo(2), Foo(3), Foo(4), Foo(5)};
    26. std::vector<Foo> to_vector(from_vector.size());
    27. std::uninitialized_copy(from_vector.begin(), from_vector.end(), to_vector.begin());
    28. std::cout << "to_vector size: " << to_vector.size() << std::endl;
    29. for (const Foo & o : to_vector)
    30. {
    31. std::cout << "Foo: " << o.N << std::endl;
    32. }
    33. }

    输出

    将指定数量的对象复制到未初始化的内存区域

    std::uninitialized_copy_n

    template< class InputIt, class Size, class ForwardIt >
    ForwardIt uninitialized_copy_n( InputIt first, Size count, ForwardIt d_first);

    (1)(C++11 起)

    template< class ExecutionPolicy, class InputIt, class Size, class ForwardIt >
    ForwardIt uninitialized_copy_n( ExecutionPolicy&& policy, InputIt first, Size count, ForwardIt d_first);

    (2)(C++17 起)

    1) 从始于 first 的范围复制 count 个元素到始于 d_first 的未初始化内存区域,如同以

    for ( ; n > 0; ++d_first, (void) ++first, --n)
       ::new (static_cast(std::addressof(*d_first)))
          typename std::iterator_traits::value_type(*first);

    若初始化中抛异常,则以未指定顺序销毁已构造的对象。

    2) 同 (1) ,但按照 policy 执行。此重载仅若 std::is_execution_policy_v> 为 true 才参与重载决议。

    参数

    first-要复制的元素范围起始
    d_first-目标范围起始
    policy-所用的执行策略。细节见执行策略。
    类型要求
    - InputIt 必须满足遗留输入迭代器 (LegacyInputIterator) 的要求。
    - ForwardIt 必须满足遗留向前迭代器 (LegacyForwardIterator) 的要求。
    - 通过ForwardIt 合法实例的自增、赋值、比较或间接均不可抛异常。

    返回值

    指向最后复制的元素后一元素的迭代器。

    复杂度

    count 成线性。

    异常

    拥有名为 ExecutionPolicy 的模板形参的重载按下列方式报告错误:

    • 若作为算法一部分调用的函数的执行抛出异常,且 ExecutionPolicy 为标准策略之一,则调用 std::terminate 。对于任何其他 ExecutionPolicy ,行为是实现定义的。
    • 若算法无法分配内存,则抛出 std::bad_alloc 。

     可能的实现

    1. template<class InputIt, class Size, class ForwardIt>
    2. ForwardIt uninitialized_copy_n(InputIt first, Size count, ForwardIt d_first)
    3. {
    4. typedef typename std::iterator_traits<ForwardIt>::value_type Value;
    5. ForwardIt current = d_first;
    6. try {
    7. for (; count > 0; ++first, (void) ++current, --count) {
    8. ::new (static_cast<void*>(std::addressof(*current))) Value(*first);
    9. }
    10. } catch (...) {
    11. for (; d_first != current; ++d_first) {
    12. d_first->~Value();
    13. }
    14. throw;
    15. }
    16. return current;
    17. }

    调用示例

    1. #include <iostream>
    2. #include <vector>
    3. struct Foo
    4. {
    5. int N;
    6. Foo() {}
    7. explicit Foo(int n): N(n)
    8. {
    9. std::cout << "Foo(n)" << std::endl;
    10. }
    11. Foo(const Foo & o)
    12. {
    13. std::cout << "Foo(const Foo & o)" << std::endl;
    14. this->N = o.N;
    15. }
    16. Foo & operator =(const Foo &o)
    17. {
    18. std::cout << "operator =" << std::endl;
    19. this->N = o.N;
    20. return *this;
    21. }
    22. };
    23. int main()
    24. {
    25. std::vector<Foo> from_vector{Foo(1), Foo(2), Foo(3), Foo(4), Foo(5)};
    26. std::vector<Foo> to_vector(from_vector.size());
    27. std::uninitialized_copy_n(from_vector.begin(), 3, to_vector.begin());
    28. std::cout << "to_vector size: " << to_vector.size() << std::endl;
    29. for (const Foo & o : to_vector)
    30. {
    31. std::cout << "Foo: " << o.N << std::endl;
    32. }
    33. }

    输出

     

  • 相关阅读:
    基于多序列脑影像特征的机器学习分类方法
    大数据-之LibrA数据库系统告警处理(ALM-12052 TCP临时端口使用率超过阈值)
    远程管理通道安全SSH协议主机验证过程
    网页html产生随机MAC地址
    Failed to create Spark client for Spark session/30041Code
    【Flask】四、flask连接并操作数据库
    Spring Aop 面向切面编程 入门实战
    MogaFX—尼日利亚未能实现其金融包容性目标
    有哪些好的科研工具软件?
    最好的期货开户的标准是什么?
  • 原文地址:https://blog.csdn.net/qq_40788199/article/details/126803345