跳到主要内容

std::uninitialized_copy_n() 算法

// (1)
template< class InputIt, class Size, class NoThrowForwardIt >
NoThrowForwardIt uninitialized_copy_n( InputIt first, Size count, NoThrowForwardIt d_first );

// (2)
template< class ExecutionPolicy, class ForwardIt, class Size, class NoThrowForwardIt >
NoThrowForwardIt uninitialized_copy_n(
ExecutionPolicy&& policy,
ForwardIt first,
Size count,
NoThrowForwardIt d_first
);
  • (1) 从以 first 开头的范围复制 count 个元素到以 d_first 开头的未初始化内存区域,如同通过

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

    如果在初始化期间抛出异常,则已构造的对象将以未指定顺序销毁。

    未定义行为
    如果 d_first + [0, n) 与 [first; last) 重叠,则行为未定义. (自 C++20 起)
  • (2)(1) 相同,但根据 policy 执行。

重载决议

只有当 std::is_execution_policy_v<std::decay_t<ExecutionPolicy>>  (C++20 之前) std::is_execution_policy_v<std::remove_cvref_t<ExecutionPolicy>>  (C++20 起)true 时,这些重载才参与重载决议。

参数

first

要复制的元素范围的起始。

copy

要复制的元素数量。

d_first

目标范围的开头。

policy

要使用的执行策略。详见执行策略

类型要求

InputItLegacyInputIterator
ForwardIt
NoThrowForwardIt
LegacyForwardIterator

NoThrowForwardIt 的有效实例进行增量、赋值、比较或间接引用均不得抛出异常。

返回值

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

复杂度

count 成线性关系。

异常

带有模板参数 ExecutionPolicy 的重载报告错误如下

  • 如果作为算法一部分调用的函数在执行时抛出异常且 ExecutionPolicy标准策略之一,则调用std::terminate。对于非其他 ExecutionPolicy,行为是实现定义的.
  • 如果算法未能分配内存,则抛出 std::bad_alloc

可能的实现

uninitialized_copy_n (1)
template<class InputIt, class Size, class NoThrowForwardIt>
NoThrowForwardIt uninitialized_copy_n(InputIt first, Size count, NoThrowForwardIt d_first)
{
using T = typename std::iterator_traits<NoThrowForwardIt>::value_type;
NoThrowForwardIt current = d_first;
try
{
for (; count > 0; ++first, (void) ++current, --count)
::new (static_cast<void*>(std::addressof(*current))) T(*first);
}
catch (...)
{
for (; d_first != current; ++d_first)
d_first->~T();
throw;
}
return current;
}

示例

Main.cpp
#include <algorithm>
#include <iostream>
#include <memory>
#include <string>
#include <tuple>
#include <vector>

int main()
{
std::vector<std::string> v = {"This", "is", "an", "example"};

std::string* p;
std::size_t sz;
std::tie(p, sz) = std::get_temporary_buffer<std::string>(v.size());
sz = std::min(sz, v.size());

std::uninitialized_copy_n(v.begin(), sz, p);

for (std::string* i = p; i != p + sz; ++i)
{
std::cout << *i << ' ';
i->~basic_string<char>();
}
std::cout << '\n';

std::return_temporary_buffer(p);
}
输出
This is an example
本文档源自此 CppReference 页面。它可能为了改进或编辑偏好而被修改。点击“编辑此页面”查看本文档的所有更改。
悬停查看原始许可证。

std::uninitialized_copy_n() 算法

// (1)
template< class InputIt, class Size, class NoThrowForwardIt >
NoThrowForwardIt uninitialized_copy_n( InputIt first, Size count, NoThrowForwardIt d_first );

// (2)
template< class ExecutionPolicy, class ForwardIt, class Size, class NoThrowForwardIt >
NoThrowForwardIt uninitialized_copy_n(
ExecutionPolicy&& policy,
ForwardIt first,
Size count,
NoThrowForwardIt d_first
);
  • (1) 从以 first 开头的范围复制 count 个元素到以 d_first 开头的未初始化内存区域,如同通过

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

    如果在初始化期间抛出异常,则已构造的对象将以未指定顺序销毁。

    未定义行为
    如果 d_first + [0, n) 与 [first; last) 重叠,则行为未定义. (自 C++20 起)
  • (2)(1) 相同,但根据 policy 执行。

重载决议

只有当 std::is_execution_policy_v<std::decay_t<ExecutionPolicy>>  (C++20 之前) std::is_execution_policy_v<std::remove_cvref_t<ExecutionPolicy>>  (C++20 起)true 时,这些重载才参与重载决议。

参数

first

要复制的元素范围的起始。

copy

要复制的元素数量。

d_first

目标范围的开头。

policy

要使用的执行策略。详见执行策略

类型要求

InputItLegacyInputIterator
ForwardIt
NoThrowForwardIt
LegacyForwardIterator

NoThrowForwardIt 的有效实例进行增量、赋值、比较或间接引用均不得抛出异常。

返回值

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

复杂度

count 成线性关系。

异常

带有模板参数 ExecutionPolicy 的重载报告错误如下

  • 如果作为算法一部分调用的函数在执行时抛出异常且 ExecutionPolicy标准策略之一,则调用std::terminate。对于非其他 ExecutionPolicy,行为是实现定义的.
  • 如果算法未能分配内存,则抛出 std::bad_alloc

可能的实现

uninitialized_copy_n (1)
template<class InputIt, class Size, class NoThrowForwardIt>
NoThrowForwardIt uninitialized_copy_n(InputIt first, Size count, NoThrowForwardIt d_first)
{
using T = typename std::iterator_traits<NoThrowForwardIt>::value_type;
NoThrowForwardIt current = d_first;
try
{
for (; count > 0; ++first, (void) ++current, --count)
::new (static_cast<void*>(std::addressof(*current))) T(*first);
}
catch (...)
{
for (; d_first != current; ++d_first)
d_first->~T();
throw;
}
return current;
}

示例

Main.cpp
#include <algorithm>
#include <iostream>
#include <memory>
#include <string>
#include <tuple>
#include <vector>

int main()
{
std::vector<std::string> v = {"This", "is", "an", "example"};

std::string* p;
std::size_t sz;
std::tie(p, sz) = std::get_temporary_buffer<std::string>(v.size());
sz = std::min(sz, v.size());

std::uninitialized_copy_n(v.begin(), sz, p);

for (std::string* i = p; i != p + sz; ++i)
{
std::cout << *i << ' ';
i->~basic_string<char>();
}
std::cout << '\n';

std::return_temporary_buffer(p);
}
输出
This is an example
本文档源自此 CppReference 页面。它可能为了改进或编辑偏好而被修改。点击“编辑此页面”查看本文档的所有更改。
悬停查看原始许可证。