The only reason it would take a CIndex * to store and not a const CIndex * const is if it did in fact modify it.
You could do this:
std::vector< const Index *> m_vIndexes;
This tells me that the vector holds constant Index objects. And the compiler likes this as well and does not require you to cast away const later. You can still store const objects but you cannot modify what they point to and you cannot modify the objects via the vector.
So then you are passing pointer to a const object and storing the pointer in the const object vector.
This makes more sense to me. Now when you need to modify the objects later you will run into the same issue. Then you will probably have to const_cast to get it to work.
I don't think the problem is with vector's push_back method, but that you are trying to store a const pointer in a vector that is meant for non-const pointers. But since the pointer is meant to be modifiable, may-be you could drop the const-qualifiers in the add method (or use const_cast - either way you can't protect yourself from errors).
Interesting problem, though.
I agree that the problem is trying to store a const object in a vector meant for non const objects. That's why my std::vector<const index *> version works without changing the Add prototype.
Actually that vector holds pointers to constant Index objects, which is presumably what you meant. Many seem to be confused here and may be forgetting to read the type from right to left.
Originally Posted by Bubba
if you only ever intend to call const methods on those Index objects in the vector, then the above is what you should be using, and same in the add function. It's also possible that you may want mutable members in the Index class in this case, but we can't tell without seeing the code.
However if you intend to call non-const methods on those Index objects in the vector at any time, then if should not be a vector of pointers to const, and neither should the declaration of Add.
But as I did explain, other functions need to modify the pointer later, and they get it either from the map or from the vector, both of which the function tries to store the pointer in.
AddIndex is a function that is supposed to prepare and store the pointer in the array and the map.
Remember that is part of a linked list --> so it contains a lot of pointers to walk in it and those need to be updated, for example, which is exactly why I can't store a const CIndex* in the vector or the map.
EDIT: So in essence, you recommend that the AddIndex function should not take a const pointer?
Just for the record I was confused as soon as he posted. :D
>> So in essence, you recommend that the AddIndex function should not take a const pointer?
It can take a const pointer, just not a pointer to const.
In other words, I think AddIndex should take a CIndex* const pIndex rather than a const CIndex* const pIndex. It should not promise to not change the CIndex pointed to by the pointer, because by adding it to a vector that might change it later, it is essentially doing so itself.
OK, here's another one:
CreateIndex takes a constant pointer too because it doesn't modify it.
CRegistry::CIndex* CRegistry::CreateIndex(const CString& strName, const CIndex::RegType dwType, const DWORD dwTreeLevel, const CIndex* const pParent, const bool bAssignID)
Here's another one. pIndex->pParent is of type CIndex*.
pIndex = DEBUG_NEW CIndex;
pIndex->pParent = const_cast<CIndex*>(pParent); // CONST QUESTION
I guess the same principle applies here. CreateIndex doesn't modify the pointer, but it creates and returns an object that CAN be changed, so I guess I remove const here too?
Yes. If you assign a copy of the original pointer to something else that might modify the object, then that is equivalent to saying that the original pointer might modify the object. So again you should not declare the pointer as referring to a const object.