鉴于此代码(使用 C++、Qt 容器,但我认为问题是普遍的):
// 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);
}
我收到编译错误(MSVC2010):
error C2664: 'QList::indexOf' : cannot convert parameter 1 from 'const Item *' to 'Item *const &'
with
[
T=Item *
]
Conversion loses qualifiers
我认为,由于 indexOf()
是用 const T &
参数声明的,因此该参数将成为 const Item* &
(对指向 const Item 的指针的引用,可以从 const Item*
参数轻松获得。不幸的是,自从 const T& t
and T const &t
are equivalent ,出于某种原因,编译器似乎将参数视为 Item* const &t
,它读作“对指向项目的 const 指针的引用”,这是不同的事情,并且不会使 Item
指向不可变的。
我的解释正确吗?为什么即使函数以不会改变参数的方式声明,编译器也会把事情搞砸?这真的是 const 语法等价性如何把事情搞砸的情况吗?为什么编译器使用后一种形式而不是前一种形式?如果我想将指针存储在容器中并保持严格的 const 语义,我该怎么办?
最佳答案
在这种情况下,您可以使用 const_cast
删除 const
性质,而不会违反函数的保证。
// 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));
}
这是因为 indexOf
只是在容器中查找指针,而不是取消引用指针并改变另一侧的内容。
关于c++ - Const 正确性导致指针容器出现问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20599033/