Mathieu
Mathieu

Reputation: 330

How to get const references to a range of std::vector elements?

I want to get a range of elements from a std::vector<MyClass> and store them as const-ref, because I only want to read but not modify them.

#include <iostream>
#include <vector>

// A "large" user class
class MyClass 
{
public:
    int data;
    MyClass(int val) : data(val) {} 
};    

int main() 
{
    // Initialize vector to MyClass objects
    std::vector<MyClass> myClass{1, 2, 3, 4, 5, 6, 7, 8};

    // Get const reference to element with index 0
    const auto &el = myClass[0]; 

    // Get const references to a range of elements
    const unsigned int start = 1, end = 4;
    // const auto &elRange = ???

    return 0;
}

How can I achieve something like this in C++17 or lower?

Upvotes: 8

Views: 261

Answers (3)

Ahmed AEK
Ahmed AEK

Reputation: 18090

That's what std::span is made for, but you will need C++20 for it.

If you are stuck on lesser C++ versions you can use boost::span. (It needs 2 headers to include in a project, you don't need the entire boost library)

auto elements = boost::span<const MyClass>{myClass}.subspan(start, end-start);

C++17 godbolt example

Upvotes: 6

JeJo
JeJo

Reputation: 32972

I want to get a range of elements from a std::vector and store them as const references, because I only want to read but not modify them.

The best would be using std::span, which requires support.

Otherwise, you write a simple SimpleSpan class to do so. As simple as:

// A simple span-like class for C++17
template<typename T>
class SimpleSpan 
{
   T* data_;
   std::size_t size_;

public:
   constexpr SimpleSpan(T* data, std::size_t size) : data_{ data }, size_{ size } {}

   constexpr T& operator[](std::size_t index) { return data_[index]; }
   constexpr T& operator[](std::size_t index) const { return data_[index]; }

   constexpr T* begin() { return data_; }
   constexpr T* end() { return data_ + size_; }
   constexpr T* begin() const { return data_; }
   constexpr T* end() const { return data_ + size_; }

   constexpr std::size_t size() const { return size_; }
};

and just

// Get const references to a range of elements using our SimpleSpan
const unsigned int start = 1, end = 4;
SimpleSpan<const MyClass> elRange(&myClass[start], end - start);

See live demo

Upvotes: 10

3CxEZiVlQ
3CxEZiVlQ

Reputation: 38883

std::span

const auto elRange = std::span(&myClass[1], &myClass[4]);

Upvotes: 0

Related Questions