I have a templated container class, something like this toy code:
template <class ItemType> class MyVector
{
public:
MyVector() : _numItems(0), _items(NULL) {/* empty */}
/** Returns a reference to the first item in our array,
* or a default-constructed item if the array is empty.
*/
const ItemType & GetFirstItemWithDefault() const
{
return (_numItems > 0) ? _items[0] : _defaultItem;
}
[other methods omitted because they aren't relevant]
private:
int _numItems; // how many valid items (_items) points to
ItemType * _items; // demand-allocated
const ItemType _defaultItem;
};
This class is really convenient to use -- any code can just #include "MyVector.h" and then start declaring objects of type MyVector and MyVector and so on, and it all Just Works (tm) without any futzing around required.
One thing that kind of bothers me, however, is the presence of the _defaultItem member variable, which is there solely to give GetFirstItemWithDefault() the ability to return a valid reference when the container is empty. The objection is that if I declare N MyVector objects, that means N copies of _defaultItem will be present in RAM as well --- even though they are all identical and read-only, and so there really only needs to be one of them per process, not one per MyVector.
So, the obvious solution is to make _defaultItem static .... but AFAICT that comes with a cost: if I do that, it is no longer possible for any old piece of code to simply #include "MyVector.h" and go... now the user has to be sure to declare storage for that static variable in one of his .cpp files, which is (a) a pain in the butt, and (b) means that the user of the code has to be aware of the details of the internal implementation of the class. Since _defaultItem is a private member variable, the user of the class shouldn't have to think about it or even realize it exists, let alone know that he needs to declare storage for it. (and what if two separate pieces of code both declare storage for it, each not knowing the other has done the same thing? Wouldn't that cause a duplicate-symbol linker error?)
Therefore, my question is: is there any way to tell C++ to automatically provide one unique storage (per instantiated type of MyVector) for this static member variable, so that users of MyVector don't have to know about it? (Note that it would need to be automatic for all possible instantiations of MyVector<...>, not just for a few common cases)
If it is a template, the compiler will do the magic for you. Just put the static member in the header, and the compiler will see to that it is just instantiated once.
template <class ItemType>
class MyVector
{
public:
//...
private:
static const ItemType _defaultItem;
};
template <class ItemType>
const ItemType MyVector<ItemType>::_defaultItem;