C ++ 20:左半部分或右半部分是否有子范围?

问题描述

这是我要编写的代码

#include <algorithm>
#include <ranges>
#include <vector>
#include <iostream>

int main() {
    std::vector<int> v {1,2,3,4};
    std::vector<int> u (4);
    
    std::ranges::copy(v,u.begin()); // OK
    // std::ranges::copy(v + 2,u.begin()); // FAIL
    
    for (auto n : u) {
        std::cout << n << ' ';
    }
    
}

问题是-如何从起始迭代器创建子范围并将其传递给受范围限制的STL算法?

解决方法

分别使用enter image description hereviews::take,可以得到范围的左侧或右侧:

std::ranges::copy(v | std::ranges::views::take(2),// left side
                  u.begin());

std::ranges::copy(v | std::ranges::views::drop(2),// right side
                  u.begin());

这里是views::drop


通常,您还可以使用demo,它允许您从迭代器和标记值创建子范围:

std::ranges::copy(std::ranges::subrange(v.begin() + 2,v.end()),u.begin()); 

这里是std::ranges::subrange

,

尚无标准化版本。

自我解答:

#include <algorithm>
#include <iterator>
#include <ranges>
#include <vector>
#include <iostream>

template <std::ranges::random_access_range R>
auto left_half(R r) {
    return std::ranges::subrange(std::begin(r),std::begin(r) + std::ranges::size(r) / 2);
}

template <std::ranges::random_access_range R>
auto right_half(R r) {
    return std::ranges::subrange(std::begin(r) + std::ranges::size(r) / 2,std::end(r));
}

int main() {
    std::vector<int> v {1,2,3,4};
    std::vector<int> u (4);
    
    std::ranges::copy(left_half(v),u.begin());
    
    for (auto n : u) {
        std::cout << n << ' ';
    }
    
}

演示:https://wandbox.org/permlink/H1PuBlfIcftx5G9Z