Capy Bara
Capy Bara

Reputation: 11

How can I reference a vector<Derived> with a span<Base>

So my question is simple. I have std::vector<Derived> and it’s a natural desire to have a std::span<Base> to it. Derive inherits from Base:

#include <span>
#include <vector>

class Base {};
class Derived : public Base {};

int main 
{
    std::vector<Derived> vec {Derived{}, Derived{}};
    // std::span<Base> span = ???;
    return 0; 
}

I guess this is impossible. Is there any common workaround? If so, are there any limitations of that?

I’m stuck with that. I see no solution

Upvotes: 0

Views: 47

Answers (1)

Jerry Coffin
Jerry Coffin

Reputation: 489938

When you want to have a Base-view of derived objects, you're pretty much stuck with the fact that you have to do it via pointers or references.

So, you could create something like an std::array<Base *, size>, or possibly a std::array<wrapper<Base>, size>, (where wrapper acts like a reference instead of a pointer, so you don't need to dereference it explicitly--maybe std::reference_wrapper, or maybe something else).

If you don't mind doing more work on your own, you could pretty easily create a class a little like std::span that stores only a pointer to the first item (or possibly to the underlying collection) along with a count, and supports an indexing operator to return a reference to an object in the collection:

template <class Derived, class Base>
class ref_span {
    Derived *begin;
    size_t size;
public:
    ref_span(Derived *begin, size_t size)
        : begin(begin), size(size) {}

    Base &operator[](size_t index) {
        if (index >= size)
            throw std::out_of_range("Index out of range");
        return begin[index];
    }
};

Live On Godbolt

Upvotes: 1

Related Questions