Namespaces
Variants

std::replace_copy, std::replace_copy_if

От ru.cppreference.net
 
 
Библиотека алгоритмов
Ограниченные алгоритмы и алгоритмы над диапазонами (C++20)
Ограниченные алгоритмы, например ranges::copy, ranges::sort, ...
Операции последовательности без изменения    
Пакетные операции
(C++17)
Операции поиска
Операции последовательности, изменяющие элементы
Операции копирования
(C++11)
(C++11)
Операции обмена
Операции преобразования
Операции генерации
Операции удаления
Операции изменения порядка
(until C++17)(C++11)
(C++20)(C++20)
Операции выборки
(C++17)

Сортировка и связанные операции
Операции разделения
(C++11)    

Операции сортировки
Операции бинарного поиска
(на разделённых диапазонах)
Операции над множествами (на отсортированных диапазонах)
Операции слияния (на отсортированных диапазонах)
Операции над кучей
Операции минимума/максимума
(C++11)
(C++17)
Операции лексикографического сравнения
Операции перестановок


Политики выполнения (C++17)
(только для пояснения*)(C++26)

Численные операции
(C++11)
(C++17)
(C++17)    

Специализированные <memory> алгоритмы

Специализированные <random> алгоритмы
Библиотека C









 
Определены в заголовке <algorithm>
template< class InputIt, class OutputIt, class T >
OutputIt replace_copy( InputIt first, InputIt last, OutputIt d_first,
                       const T& old_value, const T& new_value );
(1) (constexpr начиная с C++20)
template< class ExecutionPolicy,
          class ForwardIt1, class ForwardIt2, class T >
ForwardIt2 replace_copy
    ( ExecutionPolicy&& policy,
      ForwardIt1 first, ForwardIt1 last, ForwardIt2 d_first,
      const T& old_value, const T& new_value );
(2) (начиная с C++17)
template< class InputIt, class OutputIt, class UnaryPred, class T >
OutputIt replace_copy_if
    ( InputIt first, InputIt last, OutputIt d_first,
      UnaryPred p, const T& new_value );
(3) (до C++26)
(constexpr начиная с C++20)
template< class InputIt, class OutputIt, class UnaryPred,
          class T = typename std::iterator_traits
                        <OutputIt>::value_type >
constexpr OutputIt replace_copy_if
    ( InputIt first, InputIt last, OutputIt d_first,
      UnaryPred p, const T& new_value );
(начиная с C++26)
template< class ExecutionPolicy, class ForwardIt1, class ForwardIt2,
          class UnaryPred, class T >
ForwardIt2 replace_copy_if
    ( ExecutionPolicy&& policy,
      ForwardIt1 first, ForwardIt1 last, ForwardIt2 d_first,
      UnaryPred p, const T& new_value );
(4) (начиная с C++17)
(до C++26)
template< class ExecutionPolicy, class ForwardIt1, class ForwardIt2,
          class UnaryPred, class T = typename std::iterator_traits
                                         <ForwardIt2>::value_type >
ForwardIt2 replace_copy_if
    ( ExecutionPolicy&& policy,
      ForwardIt1 first, ForwardIt1 last, ForwardIt2 d_first,
      UnaryPred p, const T& new_value );
(начиная с C++26)

Копирует элементы из диапазона [first, last) в другой диапазон, начиная с d_first, заменяя все элементы, удовлетворяющие определённым критериям, на new_value.

1) Заменяет все элементы, равные old_value (используя operator==).
3) Заменяет все элементы, для которых предикат p возвращает true.
2,4) Аналогичны (1,3), но выполняются в соответствии с policy.
Эти перегрузки участвуют в разрешении перегрузок только если значение следующего выражения равно true:

std::is_execution_policy_v<std::decay_t<ExecutionPolicy>>

(до C++20)

std::is_execution_policy_v<std::remove_cvref_t<ExecutionPolicy>>

(начиная с C++20)

Если хотя бы один из результатов выражений *first и new_value не может быть writable в d_first, программа считается некорректной.

Если исходный и целевой диапазоны перекрываются, поведение не определено.

Параметры

first, last - пара итераторов, определяющих исходный диапазон элементов для копирования
d_first - начало диапазона назначения
old_value - значение элементов для замены
policy - политика выполнения для использования
p - унарный предикат, который возвращает ​ true если значение элемента должно быть заменено.

Выражение p ( v ) должно быть преобразуемо в bool для каждого аргумента v типа (возможно const) VT , где VT - тип значения InputIt , независимо от категории значения , и не должно изменять v . Таким образом, тип параметра VT & не допускается , как и VT , если для VT перемещение не эквивалентно копированию (since C++11) . ​

new_value - значение для использования в качестве замены
Требования к типам
-
InputIt должен удовлетворять требованиям LegacyInputIterator .
-
OutputIt должен удовлетворять требованиям LegacyOutputIterator .
-
ForwardIt1, ForwardIt2 должен удовлетворять требованиям LegacyForwardIterator .

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

Итератор на элемент, следующий за последним скопированным элементом.

Сложность

Дано N как std:: distance ( first, last ) :

1,2) Ровно N сравнений с использованием operator == .
3,4) Ровно N применений предиката p .

Исключения

Перегрузки с параметром шаблона с именем ExecutionPolicy сообщают об ошибках следующим образом:

  • Если выполнение функции, вызванной как часть алгоритма, выбрасывает исключение и ExecutionPolicy является одним из стандартных политик , std::terminate вызывается. Для любой другой ExecutionPolicy поведение определяется реализацией.
  • Если алгоритму не удается выделить память, std::bad_alloc выбрасывается.

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

replace_copy (1)
template<class InputIt, class OutputIt, class T>
OutputIt replace_copy(InputIt first, InputIt last, OutputIt d_first,
                      const T& old_value, const T& new_value)
{
    for (; first != last; ++first)
        *d_first++ = (*first == old_value) ? new_value : *first;
    return d_first;
}
replace_copy_if (3)
template<class InputIt, class OutputIt, class UnaryPred,
         class T = typename std::iterator_traits<ForwardIt>::value_type>
OutputIt replace_copy_if(InputIt first, InputIt last, OutputIt d_first,
                         UnaryPred p, const T& new_value)
{
    for (; first != last; ++first)
        *d_first++ = p(*first) ? new_value : *first;
    return d_first;
}
**Примечание:** Весь код C++ внутри тегов `
` и `` оставлен без изменений, как и требовалось. HTML-теги и атрибуты также сохранены в оригинальном виде.

Примечания

Макрос тестирования возможностей Значение Стандарт Возможность
__cpp_lib_algorithm_default_value_type 202403 (C++26) Списковая инициализация для алгоритмов ( 3,4 )

Пример

#include <algorithm>
#include <complex>
#include <iostream>
#include <vector>
void println(const auto& seq)
{
    for (const auto& e : seq)
        std::cout << e << ' ';
    std::cout << '\n';
}
int main()
{
    std::vector<short> src{3, 1, 4, 1, 5, 9, 2, 6, 5};
    println(src);
    std::vector<int> dst(src.size());
    std::replace_copy_if(src.cbegin(), src.cend(),
                         dst.begin(),
                         [](short n){ return n > 5; }, 0);
    println(dst);
    std::vector<std::complex<double>> src2{{1, 3}, {2, 4}, {3, 5}},
                                      dst2(src2.size());
    println(src2);
    #ifdef __cpp_lib_algorithm_default_value_type
        std::replace_copy_if(src2.cbegin(), src2.cend(), dst2.begin(),
            [](std::complex<double> z){ return std::abs(z) < 5; },
            {4, 2}); // Возможно, так как T выводится.
    #else
        std::replace_copy_if(src2.cbegin(), src2.cend(), dst2.begin(),
            [](std::complex<double> z){ return std::abs(z) < 5; },
            std::complex<double>{4, 2});
    #endif
    println(dst2);
}

Вывод:

3 1 4 1 5 9 2 6 5 
3 1 4 1 5 0 2 0 5 
(1,3) (2,4) (3,5) 
(4,2) (4,2) (3,5)

Отчёты о дефектах

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

DR Applied to Behavior as published Correct behavior
LWG 283 C++98 T was required to be CopyAssignable (and EqualityComparable for
replace_copy ), but the value type of InputIt is not always T
removed the requirement
LWG 337 C++98 replace_copy_if only required InputIt to
meet the requirements of LegacyIterator [1]
corrected to
LegacyInputIterator
  1. ↑ Фактический дефект в стандарте C++ заключается в том, что шаблонный параметр InputIterator был некорректно указан как Iterator . Это влияет на требования к типам, поскольку стандарт C++ утверждает, что для шаблонов функций в библиотеке алгоритмов, параметры шаблонов, имя которых заканчивается на Iterator , подразумевают требования к типам соответствующих категорий итераторов.

См. также

заменяет все значения, удовлетворяющие определённым критериям, на другое значение
(шаблон функции & функциональный объект алгоритма)
удаляет элементы, удовлетворяющие определённым критериям
(шаблон функции & функциональный объект алгоритма)
копирует диапазон, заменяя элементы, удовлетворяющие определённым критериям, на другое значение
(функциональный объект алгоритма)