Spec-Zone.ru › C++

std::ranges::uninitialized_fill

Определено в заголовке <memory>
Вызов
template< no-throw-forward-iterator I, no-throw-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& x );
(1) (с C++20)
template< no-throw-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& x );
(2) (с C++20)
1) Создаёт \( \scriptsize N \)N копий заданного значения x в неинициализированной области памяти, обозначенной диапазоном [first, last), где \( \scriptsize N \)N — ranges::distance(first, last).
Функция эквивалентна:
for (; first != last; ++first)
    ::new (static_cast<void*>(std::addressof(*first)))
        std::remove_reference_t<std::iter_reference_t<I>>(x);
return first;
Если во время инициализации возникает исключение, уже созданные объекты уничтожаются в неопределённом порядке.
2) Аналогично (1), но использует r в качестве диапазона, как если бы ranges::begin(r) использовалось как first, а ranges::end(r) как last.

Функциональные сущности, описанные на этой странице, являются неблоидами, то есть:

  • Явные списки шаблонных аргументов указать при вызове нельзя.
  • Ни один из них не виден для поиска аргументов зависящих от шаблона.
  • Если любой из них обнаружен обычным безусловным поиском в качестве имени слева от оператора вызова функции, поиск аргументов зависящих от шаблона подавляется.

На практике они могут быть реализованы как объекты-функции или с использованием специальных расширений компилятора.

Параметры

first, last - пара итератор-стоп-итератор, обозначающая диапазон элементов для инициализации
r - диапазон элементов для инициализации
value - значение для создания элементов

Возвращаемое значение

Итератор, равный last.

Сложность

\( \scriptsize \mathcal{O}(N) \)𝓞(N).

Исключения

Исключение, брошенное при создании элементов в целевом диапазоне, если таковое имеется.

Примечания

Реализация может повысить эффективность ranges::uninitialized_fill, например, используя ranges::fill, если тип значения выходного диапазона является TrivialType.

Возможная реализация

struct uninitialized_fill_fn
{
    template<no-throw-forward-iterator I, no-throw-sentinel-for<I> S, class T>
    requires std::constructible_from<std::iter_value_t<I>, const T&>
    I operator()(I first, S last, const T& x) const
    {
        I rollback{first};
        try
        {
            for (; !(first == last); ++first)
                ranges::construct_at(std::addressof(*first), x);
            return first;
        }
        catch (...)
        {   
            // rollback: destroy constructed elements
            for (; rollback != first; ++rollback)
                ranges::destroy_at(std::addressof(*rollback));
            throw;
        }
    }
 
    template<no-throw-forward-range R, class T>
    requires std::constructible_from<ranges::range_value_t<R>, const T&>
    ranges::borrowed_iterator_t<R>
    operator()(R&& r, const T& x) const
    {
        return (*this)(ranges::begin(r), ranges::end(r), x);
    }
};
 
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 ▄▀▄▀▄▀▄▀

Отчёты об ошибках

Следующие отчёты об ошибках, изменяющие поведение, были применены ретроактивно к ранее опубликованным стандартам C++.

Отчёт об ошибке Применено к Поведение, опубликованное Корректное поведение
LWG 3870 C++20 Этот алгоритм может создавать объекты в const хранилище Оставлено запрещённым

См. также

ranges::uninitialized_fill_n
(C++20)
копирует объект в неинициализированную область памяти, определённую началом и количеством
(неблоид)
uninitialized_fill
копирует объект в неинициализированную область памяти, определённую диапазоном
(шаблон функции)

© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/cpp/memory/ranges/uninitialized_fill

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API