跳到主要内容

std::ranges::move() 算法

// (1)
constexpr move_result<I, O>
move( I first, S last, O result );

// (2)
constexpr move_result<ranges::borrowed_iterator_t<R>, O>
move( R&& r, O result );

参数类型是泛型的,并具有以下约束:

  • I - std::input_iterator
  • S - std::sentinel_for<I>
  • O - std::weakly_incrementable
  • (2) - R - std::ranges::input_range

此外,每个重载都有以下约束

  • (1) - std::indirectly_movable<I, O>
  • (2) - std::indirectly_movable<ranges::iterator_t<R>, O>

辅助类型定义如下:

template< class I, class O >
using move_result = ranges::in_out_result<I, O>;
  • (1) 将由 [first; last) 定义的范围内的元素移动到从 result 开始的另一个范围。

    从其中移动的范围中的元素仍将包含适当类型的有效值,但不一定是移动之前相同的值。

    未定义行为

    如果 result 在范围 [first; last) 内,则行为未定义。在这种情况下,可以改用 ranges::move_backward

  • (2)(1) 相同,但使用 r 作为源范围,如同使用 ranges::begin(r) 作为 firstranges::end(r) 作为 last

本页描述的函数类实体是niebloids

参数

first
last

要移动的元素范围。

r

要移动的元素范围。

result

目标范围的开头。

返回值

类型为 ranges::move_result 的值,初始化如下

{
last,
result + N
}

其中 N 是要从中移动元素的范围的大小。

复杂度

恰好 N 次移动赋值。

异常

(无)

可能的实现

move(1) 和 move(2)
struct move_fn
{
template<std::input_iterator I, std::sentinel_for<I> S, std::weakly_incrementable O>
requires std::indirectly_movable<I, O>
constexpr ranges::move_result<I, O>
operator()(I first, S last, O result) const
{
for (; first != last; ++first, ++result)
*result = ranges::iter_move(first);
return {std::move(first), std::move(result)};
}
template<ranges::input_range R, std::weakly_incrementable O>
requires std::indirectly_movable<ranges::iterator_t<R>, O>
constexpr ranges::move_result<ranges::borrowed_iterator_t<R>, O>
operator()(R&& r, O result) const
{
return (*this)(ranges::begin(r), ranges::end(r), std::move(result));
}
};

inline constexpr move_fn move {};

备注

在移动重叠范围时,ranges::move 适用于向左移动(目标范围的开头在源范围之外),
ranges::move_backward 适用于向右移动(目标范围的结尾在源范围之外)。

示例

以下代码将线程对象(它们本身不可复制)从一个容器移动到另一个容器。

Main.cpp
#include <algorithm>
#include <chrono>
#include <iostream>
#include <iterator>
#include <list>
#include <thread>
#include <vector>
using namespace std::literals::chrono_literals;

void f(std::chrono::milliseconds n)
{
std::this_thread::sleep_for(n);
std::cout << "thread with n=" << n.count() << "ms ended" << std::endl;
}

int main()
{
std::vector<std::jthread> v;
v.emplace_back(f, 400ms);
v.emplace_back(f, 600ms);
v.emplace_back(f, 800ms);

std::list<std::jthread> l;

// std::ranges::copy() would not compile, because std::jthread is non-copyable
std::ranges::move(v, std::back_inserter(l));
}
输出
thread with n=400ms ended
thread with n=600ms ended
thread with n=800ms ended
本文源自此 CppReference 页面。它可能为了改进或编辑者偏好而进行了更改。点击“编辑此页面”查看本文档的所有更改。
悬停查看原始许可证。

std::ranges::move() 算法

// (1)
constexpr move_result<I, O>
move( I first, S last, O result );

// (2)
constexpr move_result<ranges::borrowed_iterator_t<R>, O>
move( R&& r, O result );

参数类型是泛型的,并具有以下约束:

  • I - std::input_iterator
  • S - std::sentinel_for<I>
  • O - std::weakly_incrementable
  • (2) - R - std::ranges::input_range

此外,每个重载都有以下约束

  • (1) - std::indirectly_movable<I, O>
  • (2) - std::indirectly_movable<ranges::iterator_t<R>, O>

辅助类型定义如下:

template< class I, class O >
using move_result = ranges::in_out_result<I, O>;
  • (1) 将由 [first; last) 定义的范围内的元素移动到从 result 开始的另一个范围。

    从其中移动的范围中的元素仍将包含适当类型的有效值,但不一定是移动之前相同的值。

    未定义行为

    如果 result 在范围 [first; last) 内,则行为未定义。在这种情况下,可以改用 ranges::move_backward

  • (2)(1) 相同,但使用 r 作为源范围,如同使用 ranges::begin(r) 作为 firstranges::end(r) 作为 last

本页描述的函数类实体是niebloids

参数

first
last

要移动的元素范围。

r

要移动的元素范围。

result

目标范围的开头。

返回值

类型为 ranges::move_result 的值,初始化如下

{
last,
result + N
}

其中 N 是要从中移动元素的范围的大小。

复杂度

恰好 N 次移动赋值。

异常

(无)

可能的实现

move(1) 和 move(2)
struct move_fn
{
template<std::input_iterator I, std::sentinel_for<I> S, std::weakly_incrementable O>
requires std::indirectly_movable<I, O>
constexpr ranges::move_result<I, O>
operator()(I first, S last, O result) const
{
for (; first != last; ++first, ++result)
*result = ranges::iter_move(first);
return {std::move(first), std::move(result)};
}
template<ranges::input_range R, std::weakly_incrementable O>
requires std::indirectly_movable<ranges::iterator_t<R>, O>
constexpr ranges::move_result<ranges::borrowed_iterator_t<R>, O>
operator()(R&& r, O result) const
{
return (*this)(ranges::begin(r), ranges::end(r), std::move(result));
}
};

inline constexpr move_fn move {};

备注

在移动重叠范围时,ranges::move 适用于向左移动(目标范围的开头在源范围之外),
ranges::move_backward 适用于向右移动(目标范围的结尾在源范围之外)。

示例

以下代码将线程对象(它们本身不可复制)从一个容器移动到另一个容器。

Main.cpp
#include <algorithm>
#include <chrono>
#include <iostream>
#include <iterator>
#include <list>
#include <thread>
#include <vector>
using namespace std::literals::chrono_literals;

void f(std::chrono::milliseconds n)
{
std::this_thread::sleep_for(n);
std::cout << "thread with n=" << n.count() << "ms ended" << std::endl;
}

int main()
{
std::vector<std::jthread> v;
v.emplace_back(f, 400ms);
v.emplace_back(f, 600ms);
v.emplace_back(f, 800ms);

std::list<std::jthread> l;

// std::ranges::copy() would not compile, because std::jthread is non-copyable
std::ranges::move(v, std::back_inserter(l));
}
输出
thread with n=400ms ended
thread with n=600ms ended
thread with n=800ms ended
本文源自此 CppReference 页面。它可能为了改进或编辑者偏好而进行了更改。点击“编辑此页面”查看本文档的所有更改。
悬停查看原始许可证。