Quick VoidArray Question


#1

Hi, I’m interested in the thinking behind the removal of VoidArray which took place a little while ago. I’ve used a fair amount of VoidArrays in the past but I’ve always thought it would be better to implement the underlying Array code using void pointers and using a (lightweight) privately inherited template class to introduce the type safety. I first read about this technique in Scott Meyer’s ‘Effective C++’ (Item 42). But given that something like that hasn’t been introduced, surely I should still carry on using Array<void *> to avoid bloating my code? So why remove VoidArray?

Mainly just idle curiosity really. I ought to stop fussing and get back to work! :slight_smile:


#2

Well, a few reasons

  1. I stopped worrying about code bloat, and I don’t really think this was ever really a problem anyway. I also started being optimistic that when the linker sees two methods that contain identical (assembly) code, e.g. Array<X*>::add() and Array<Y*>::add(), it’ll be smart enough to dedupe them.
  2. I changed Array to make it better at handling copy-by-value objects, and started using those whenever possible instead of pointers. I think that the only Array<void*> in the codebase are now a few old legacy bits and pieces that I’ll tidy up eventually.
  3. Using VoidArray makes your code a mess!

Re: using void*s underneath - that might be possible with OwnedArray, but Array can use any kind of object, not just pointers, so it wouldn’t work for that. I’ve got a couple of Meyers books, but not that one, so what’s the general idea? Is it just to move some of the work out of the templated class into a non-templated class to avoid code duplication?


#3

That’s just what I was hoping you’d say :slight_smile: In that case I think I can stop worrying about it too and stop using VoidArrays. You’re right it’ll make everything much neater.

Yes, that’s exactly the idea. His example is something like:

template<class T>
class Stack : private GenericStack     // Generic stack is a stack of void pointers
{
void push( T* object ) { GenericStack::push( object ); }    // These are all inline so no runtime cost
T * pop() { return static_cast<T *>( GenericStack::pop() ); }

// ... etc ...
};

Obviously it would be a lot more complicated for a proper array class but that’s the general idea. Anyway, I thought I’d read somewhere that modern linkers might be able to do this sort of thing without the need for all this clever stuff (as you say) but I couldn’t for the life of me remember where!

Thanks for clearing this up :slight_smile:

Bennie