◐ Shell
clean mode source ↗

std::ranges::uninitialized_fill - cppreference.com

来自cppreference.com

在标头 <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) 如同用以下方式以给定值 value 构造目标范围 [firstlast) 中的元素:

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 执行。

此页面上描述的函数式实体是算法函数对象(非正式地称为 niebloid),即:

参数

first, last - 要初始化的元素范围的迭代器-哨位对
r - 要初始化的元素 range
value - 用以构造元素的值
policy - 所用的执行策略

返回值

如上所述。

异常

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

注解

如果输出范围的值类型是平凡类型 (TrivialType) ,那么实现可以提升 ranges::uninitialized_fill 的效率(例如用 ranges::fill)。

功能特性测试 标准 功能特性
__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 (...)
        {
            // 回滚:销毁已构造的元素
            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 << "异常!\n";
    }
}

输出:

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

参阅