David Wilkinson wrote:
1. I have never really seen the point of the double template argument in
the MFC collection classes, and to this day I find it confusing. CArray
always returns elements by const or non-const reference to TYPE (as does
std::vector). ARG_TYPE is only used when inserting elements, so why
would one ever choose ARG_TYPE to be anything but const ARG& (same as
std::vector)? Maybe I am missing something...
Correction: I meant why would one ever choose ARG_TYPE to be anything
but const TYPE& ?
Interestingly, I see that ARG_TYPE is defaulted to const TYPE& in the
latest version of vc that I have (7.1). Even more interesting, I see
that various signatures for extracting elements from CArray have changed
over the years. I do not have VC6, but VC5 and VC7.1 are like this:
VC5:
class CArray : public CObject
{
TYPE GetAt(int nIndex) const;
TYPE& ElementAt(int nIndex);
TYPE operator[](int nIndex) const;
TYPE& operator[](int nIndex);
};
VC7.1:
template<class TYPE, class ARG_TYPE = const TYPE&>
class CArray : public CObject
{
const TYPE& GetAt(INT_PTR nIndex) const;
TYPE& GetAt(INT_PTR nIndex);
const TYPE& ElementAt(INT_PTR nIndex) const;
TYPE& ElementAt(INT_PTR nIndex);
const TYPE& operator[](INT_PTR nIndex) const;
TYPE& operator[](INT_PTR nIndex);
};
The VC7.1 version is essentially the same as std::vector in this
respect, except that ElementAt() now seems redundant. Even so, the
documentation for ElementAt still says
"Returns a temporary reference to the element pointer within the array."
which seems to ignore the fact that all the above methods now return a
reference that might be temporary. In fact the non-const version of
operator [] always did that also.
Note that none of the above, now or ever, return ARG_TYPE, or ARG_TYPE&,
although (googling through the newsgroups) it would appear that some
people believe that ARG_TYPE controls what is returned from the array as
well as how elements are inserted.
Another thing is that the recommendation was always to do
CArray<MyClass, MyClass&> myArray;
rather than const MyClass& as the second template argument. Doesn't this
unnecessarily preclude inserting a constant object into a CArray?
To be fair, the implementation (if not the documentation) in VC7 seems
improved in these respects, but I would be happier to see size_t in all
the arguments, rather than INT_PTR. Maybe size_t and INT_PTR are always
the same in both Win32 and Win64, but aren't they logically different?
And then there's ConstructElements() and DestructElements(), which I
never understood.
All in all, I don't think these MFC collection classes were very well
designed.
David Wilkinson