Namespaces
Variants

std::ranges::uninitialized_fill

来自 zh.cppreference.net
 
 
算法库
受约束算法及范围算法 (C++20)
受约束算法,例如 ranges::copy、ranges::sort……
排序及相关操作
划分操作
(C++11)    

排序操作
二分搜索操作
(在已划分的范围上)
集合操作 (在已排序的范围上)
合并操作 (在已排序的范围上)
堆操作
最小/最大操作
(C++11)
(C++17)
字典序比较操作
排列操作


 
 
定义于头文件 <memory>
调用签名
template< /*nothrow-forward-iterator*/ I, /*nothrow-sentinel-for*/<I> S,
          class T >
    requires std::constructible_from<std::iter_value_t<I>, const T&>
I uninitialized_fill( I first, S last, const T& value );
(1) (C++20 起)
(C++26 起 constexpr)
template< /*nothrow-forward-range*/ R, class T >
    requires std::constructible_from<ranges::range_value_t<R>, const T&>
ranges::borrowed_iterator_t<R> uninitialized_fill( R&& r,
                                                   const T& value );
(2) (C++20 起)
(C++26 起 constexpr)
template< /*execution-policy*/ Ep, /*nothrow-random-access-iterator*/ I,
          /*nothrow-sized-sentinel-for*/<I> S,
          class T = std::iter_value_t<I> >
    requires constructible_from<std::iter_value_t<I>, const T&>
I uninitialized_fill( Ep&& policy, I first, S last, const T& value );
(3) (C++26 起)
template< /*execution-policy*/ Ep, /*nothrow-sized-random-access-range*/ R,
          class T = ranges::range_value_t<R> >
    requires std::constructible_from<ranges::range_value_t<R>, const T&>
ranges::borrowed_iterator_t<R> uninitialized_fill( Ep&& policy, R&& r,
                                                   const T& value );
(4) (C++26 起)

关于 /*execution-policy*/ 的定义,参见 此页面;关于其他仅供说明的概念的定义,参见 此页面。

1) 在目标范围 [first, last) 中构造元素,赋予给定值 value,如同通过以下方式:

for (; first != last; ++first)
    ::new (voidify(*first)) std::remove_reference_t<std::iter_reference_t<I>>(value);
return first;

如果初始化过程中抛出异常,则已构造的对象将以未指定的顺序被销毁。
2) 与 (1) 相同,但将 r 用作目标范围。
3,4) 与 (1,2) 相同,但根据 policy 执行。

本页描述的函数式实体是 算法函数对象(非正式名称为 niebloids),即:

参数

first, last - 定义要初始化的元素的范围的迭代器-哨兵对
r - 要初始化的元素的范围
value - 用于构造元素的值
policy - 要使用的执行策略

返回值

如上所述。

异常

在目标范围内构造元素时抛出的任何异常。

3,4) 在执行过程中:
  • 如果并行化所需的临时内存资源不可用,则会抛出 std::bad_alloc。
  • 如果在通过算法参数访问对象时抛出了未被捕获的异常,则行为由执行策略决定(对于 标准策略,会调用 std::terminate)。

注意

实现可能会提高 ranges::uninitialized_fill 的效率(例如使用 ranges::fill),如果输出范围的值类型是 TrivialType。

特性测试 宏 值 标准 特性
__cpp_lib_parallel_algorithm 202506L (C++26) 并行范围算法
__cpp_lib_raw_memory_algorithms 202411L (C++26) constexpr 用于 特化<memory> 算法,(1,2)

可能的实现

struct uninitialized_fill_fn
{
    template</*nothrow-forward-iterator*/ I, /*nothrow-sentinel-for*/<I> S, class T>
        requires std::constructible_from<std::iter_value_t<I>, const T&>
    constexpr I operator()(I first, S last, const T& value) const
    {
        I rollback{first};
        try
        {
            for (; !(first == last); ++first)
                ranges::construct_at(std::addressof(*first), value);
            return first;
        }
        catch (...)
        {   
            // rollback: destroy constructed elements
            for (; rollback != first; ++rollback)
                ranges::destroy_at(std::addressof(*rollback));
            throw;
        }
    }

    template</*nothrow-forward-range*/ R, class T>
        requires std::constructible_from<ranges::range_value_t<R>, const T&>
    constexpr ranges::borrowed_iterator_t<R> operator()(R&& r, const T& value) const
    {
        return (*this)(ranges::begin(r),
                       ranges::next(ranges::begin(r), ranges::end(r)), value);
    }
};

inline constexpr uninitialized_fill_fn uninitialized_fill{};

示例

#include <iostream>
#include <memory>
#include <string>
int main()
{
    constexpr int n{4};
    alignas(alignof(std::string)) char out[n * sizeof(std::string)];
    try
    {
        auto first{reinterpret_cast<std::string*>(out)};
        auto last{first + n};
        std::ranges::uninitialized_fill(first, last, "▄▀▄▀▄▀▄▀");
        int count{1};
        for (auto it{first}; it != last; ++it)
            std::cout << count++ << ' ' << *it << '\n';
        std::ranges::destroy(first, last);
    }
    catch(...)
    {
        std::cout << "Exception!\n";
    }
}

输出:

1 ▄▀▄▀▄▀▄▀
2 ▄▀▄▀▄▀▄▀
3 ▄▀▄▀▄▀▄▀
4 ▄▀▄▀▄▀▄▀

参阅

复制对象到由起点和计数定义的未初始化内存区域
(算法函数对象)
复制对象到由范围定义的未初始化内存区域
(函数模板)