Const correctness causing problems with containers for pointers?

僤鯓⒐⒋嵵緔 提交于 2019-12-10 11:33:13

问题


Given this code (C++, Qt containers are used but I suppose the question is universal):

// a containter for Item-s
QList<Item*> items;

// argument is const to prevent changing the item by this function
void doStuff(const Item *item)
{
    // find index of the item inside the container
    // indexOf() is declared as:
    // template <typename T> int QList<T>::indexOf(const T &t, int from = 0) const
    const int itemIndex = items->indexOf(item);
}

I get a compile error (MSVC2010):

error C2664: 'QList::indexOf' : cannot convert parameter 1 from 'const Item *' to 'Item *const &'
with
[
T=Item *
]
Conversion loses qualifiers

I figurer that since indexOf() is declared with a const T & argument, the argument would become a const Item* & (reference to a pointer to an Item that's const) which is easily obtainable from a const Item* argument. Unfortunately, since const T& t and T const &t are equivalent, for some reason the compiler seems to treat the argument as Item* const &t which reads as "reference to a const pointer to an item" which is a different thing and doesn't make the Item pointed to immutable.

Am I interpreting this correctly? Why does the compiler screw things up even though the function is declared in a way that says it won't alter the argument? Is this really a case of how the const syntax equivalence can screw things up? Why does the compiler use the latter form over the former? What can I do about it if I want to store pointers in containters and maintain strict const semantics?


回答1:


This is a case where you can use const_cast to remove the const-ness without violating the guarantee of your function.

// argument is const to prevent changing the item by this function
void doStuff(const Item *item)
{
    // find index of the item inside the container
    // indexOf() is declared as:
    // template <typename T> int QList<T>::indexOf(const T &t, int from = 0) const
    const int itemIndex = items->indexOf(const_cast<Item*>(item));
}

That's because indexOf is merely finding the pointer in the container, not dereferencing the pointer and mutating what's on the other side.



来源:https://stackoverflow.com/questions/20599033/const-correctness-causing-problems-with-containers-for-pointers

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!