Slicing a vector in C++

PythonC++VectorSlice

Python Problem Overview


Is there an equivalent of list slicing [1:] from Python in C++ with vectors? I simply want to get all but the first element from a vector.

Python's list slicing operator:

list1 = [1, 2, 3]
list2 = list1[1:]  

print(list2) # [2, 3]

C++ Desired result:

std::vector<int> v1 = {1, 2, 3};
std::vector<int> v2;
v2 = v1[1:];

std::cout << v2 << std::endl;  //{2, 3}

Python Solutions


Solution 1 - Python

This can easily be done using std::vector's copy constructor:

v2 = std::vector<int>(v1.begin() + 1, v1.end());

Solution 2 - Python

In C++20 it is pretty easy:

#include <span>
#include <vector>
#include <iostream>

template<int left = 0, int right = 0, typename T>
constexpr auto slice(T&& container)
{
    if constexpr (right > 0)
    {
        return std::span(begin(std::forward<T>(container))+left, begin(std::forward<T>(container))+right);
    }
    else
    {
        return std::span(begin(std::forward<T>(container))+left, end(std::forward<T>(container))+right);
    }
}



int main()
{
    std::vector v{1,2,3,4,5,6,7,8,9};

    std::cout << "-------------------" << std::endl;
    auto v0 = slice<1,0>(v);
    for (auto i : v0)
    {
        std::cout << i << std::endl;
    }

    std::cout << "-------------------" << std::endl;
    auto v1 = slice<0,-1>(v);
    for (auto i : v1)
    {
        std::cout << i << std::endl;
    }

    std::cout << "-------------------" << std::endl;
    auto v2 = slice<1,3>(v);
    for (auto i : v2)
    {
        std::cout << i << std::endl;
    }

    std::cout << "-------------------" << std::endl;
    auto v3 = slice<1,-1>(v);
    for (auto i : v3)
    {
        std::cout << i << std::endl;
    }

    std::cout << "-------------------" << std::endl;
    auto v4 = slice<3,3>(v);
    for (auto i : v4)
    {
        std::cout << i << std::endl;
    }

}

Result:

Program returned: 0
-------------------
2
3
4
5
6
7
8
9
-------------------
1
2
3
4
5
6
7
8
-------------------
2
3
-------------------
2
3
4
5
6
7
8
-------------------

You can also add boundary checks and other cases like negative left indices etc... but this is only an example.

Run in compiler explorer: https://godbolt.org/z/qeaxvjdbj

Solution 3 - Python

I know it's late but have a look at valarray and its slices. If you are using a vector of some sort of NumericType, then it's worth giving it a try.

Solution 4 - Python

It depends on whether you want a view or a copy.

Python's slicing for lists copies references to the elements, so it cannot be simply regarded as a view or a copy. For example,

list1 = [1, 2, 3]
list2 = list1[1:]  
list2[1] = 5
print(list1) # does not change, still [1, 2, 3]

list1 = [1, 2, [3]]
list2 = list1[1:]  
list2[1][0] = 5
print(list1) # changes, becomes [1, 2, [5]]

See this post for details.

DimChtz's anwer models the copy situation. If you just want a view, in C++20, you can use ranges (besides std::views::drop, std::views::take and std::views::counted are also useful):

auto v2 = v1 | std::views::drop(1); // #include <ranges>
for (auto &e: v2) std::cout << e << '\n';  

or std::span:

std::span v2{v1.begin() + 1, v1.end()}; // #include <span>
for (auto &e: v2) std::cout << e << '\n';  

Solution 5 - Python

You can follow the above answer. It's always better to know multiple ways.

int main
{
    std::vector<int> v1 = {1, 2, 3};
    std::vector<int> v2{v1};
    v2.erase( v2.begin() );
    return 0;
}

Solution 6 - Python

It seems that the cheapest way is to use pointer to the starting element and the number of elements in the slice. It would not be a real vector but it will be good enough for many uses.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionWizardView Question on Stackoverflow
Solution 1 - PythonDimChtzView Answer on Stackoverflow
Solution 2 - PythonmnesarcoView Answer on Stackoverflow
Solution 3 - PythonAdrianView Answer on Stackoverflow
Solution 4 - PythonxskxzrView Answer on Stackoverflow
Solution 5 - PythonSadaananth AnbucheliyanView Answer on Stackoverflow
Solution 6 - Pythonuuu777View Answer on Stackoverflow