Re: Covariant vectors
Al wrote:
Hi all,
I've been looking for a way to simulate covariant, const, vectors for
some time. From another thread, it seems as though vectors are supposed
to be allocated contiguously.
That's the general idea.
So I wonder if the technique below is safe and legal in the general
case. In particular, I'm not sure if given virtual or multiple
inheritance, the pointers would be adjusted properly.
No, it's not safe, and inheritance isn't likely to help you.
// Foo.hpp
struct Base { int a; };
void Foo(Base*, size_t);
// Foo.cpp
#include <iostream>
#include "Foo.hpp"
void Foo(Base* array, size_t size)
{
for (size_t i = 0; i < size; ++i)
std::cout << array[i].a << std::endl;
}
You can't really apply this technique generally. The problem is that
array[1] starts at &array[0] + sizeof(Base), so if array is *actually*
an array of Derived, array[1] won't start at the right place. Crashes
are likely to result.
// Bar.cpp
#include <vector>
#include "Foo.hpp"
struct Derived : public Base {};
template <class VectorT>
void ApplyFoo(VectorT& v)
{
Foo(v.empty() ? NULL : &v[0], v.size());
};
void Bar()
{
std::vector<Base> bases;
std::vector<Derived> deriveds;
ApplyFoo(bases);
ApplyFoo(deriveds);
}
If unsafe, is there a way to make it safe?
There is. Try this instead:
void Foo(Base & b)
{
std::cout << b.a << std::endl;
}
template <class Container>
void ApplyFoo(Container & c)
{
std::foreach(c.begin(), c.end(), Foo);
}
Also, are there other (simpler?) ways to create and use covariant
*const* containers? By const I mean that the container is not changed,
only its items are read.
I don't think that it's supposed to work this way, but I'll leave the
answer to someone else.
--
John Moeller
fishcorn@gmail.com
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]