I have an array of pointers to object class e_t :
class e_t {...};
I wrote a template class :
template <class E = e_t>
class cursor_t
{ cursor_t(e_t ** &_source, size_t _total);
e_t ** &Source;
size_t Total;
E **First();
E **Last();
E **Skip(E **, short);
};
For every function, I will for(_x to this->_total
) this->Source
and stop at the first, last or skipped dynamic_cast<E *>(*(this->Source + _x))
... Works fine and it correctly stop...
The problem comes as returning the result ! Why can't I use e_t **
as E **
(knowing E
is always descending from e_t
) ?
return dynamic_cast<E **>(this->Source + _x);
always fails at compile time...
I am Using cbuilder 5
You have over-complicated your design with too many pointer indirections. You have an array of pointers, you should simplify your interface by having the methods return individual elements of the array, as the caller shouldn't need direct access to the array itself, eg:
template <class E = e_t>
class cursor_t
{
e_t ** Source;
size_t Total, Current;
public:
cursor_t(e_t ** _source, size_t _total);
E* First();
E* Last();
E* Previous();
E* Next();
E* Skip(short count);
};
template <class E>
cursor_t<E>::cursor_t(e_t ** _source, size_t _total) :
Source(_source),
Total(_total),
Current(-1)
{
}
template <class E>
E* cursor_t<E>::First()
{
for(size_t x = 0; x < Total; ++x) {
E *e = dynamic_cast<E*>(Source[x]);
if (e) { Current = x; return e; }
}
return nullptr;
}
template <class E>
E* cursor_t<E>::Last()
{
for(size_t x = Total; x-- > 0; )
{
E *e = dynamic_cast<E*>(Source[x]);
if (e) { Current = x; return e; }
}
return nullptr;
}
template <class E>
E* cursor_t<E>::Previous()
{
if (Current < Total)
{
for (size_t x = Current; x-- > 0; )
{
E *e = dynamic_cast<E*>(Source[x]);
if (e) { Current = x; return e; }
}
}
return nullptr;
}
template <class E>
E* cursor_t<E>::Next()
{
for (size_t x = Current + 1; x < Total; ++x)
{
E *e = dynamic_cast<E*>(Source[x]);
if (e) { Current = x; return e; }
}
return nullptr;
}
template <class E>
E* cursor_t<E>::Skip(short count)
{
E *e;
if (count > 0) {
while ((e = Next()) != nullptr && --count >= 0);
}
else if (count < 0) {
while ((e = Previous()) != nullptr && ++count <= 0);
}
else if (Current < Total) {
e = static_cast<E*>(Source[Current]);
} else {
e = nullptr;
}
return e;
}
Alternatively:
template <class E = e_t>
class cursor_t
{
e_t **Source, **End, **Current;
public:
cursor_t(e_t ** _source, size_t _total);
E* First();
E* Last();
E* Previous();
E* Next();
E* Skip(short count);
};
template <class E>
cursor_t<E>::cursor_t(e_t ** _source, size_t _total) :
Source(_source),
End(_source + _total),
Current(nullptr)
{
}
template <class E>
E* cursor_t<E>::First()
{
for(e_t *t = Source; t < End; ++t) {
E *e = dynamic_cast<E*>(t);
if (e) { Current = t; return e; }
}
return nullptr;
}
template <class E>
E* cursor_t<E>::Last()
{
for(e_t *t = End; t > Source; )
{
E *e = dynamic_cast<E*>(--t);
if (e) { Current = t; return e; }
}
return nullptr;
}
template <class E>
E* cursor_t<E>::Previous()
{
if (Current)
{
for (e_t *t = Current; t > Source; )
{
E *e = dynamic_cast<E*>(--t);
if (e) { Current = t; return e; }
}
}
return nullptr;
}
template <class E>
E* cursor_t<E>::Next()
{
if (Current)
{
for (e_t *t = Current + 1; t < End; ++t)
{
E *e = dynamic_cast<E*>(t);
if (e) { Current = t; return e; }
}
}
return nullptr;
}
template <class E>
E* cursor_t<E>::Skip(short count)
{
E *e;
if (count > 0) {
while ((e = Next()) != nullptr && --count >= 0);
}
else if (count < 0) {
while ((e = Previous()) != nullptr && ++count <= 0);
}
else {
e = static_cast<E*>(Current);
}
return e;
}