Reputation: 11
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
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];
}
};
Upvotes: 1