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!
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.
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.
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?
That’s just what I was hoping you’d say 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!