const正确性导致指针容器出现问题?

时间:2013-12-15 19:54:44

标签: c++ pointers containers const-correctness

鉴于此代码(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):

  

错误C2664:'QList :: indexOf':无法将参数1从'const Item *'转换为'Item * const&amp;'
           与
           [
               T =项目*
           ]
           转换失去限定符

我认为,因为indexOf()是用const T &参数声明的,所以参数将成为const Item* &(对指向const的Item的指针的引用),这可以从一个很容易获得const Item*论点。不幸的是,由于const T& t and T const &t are equivalent,由于某种原因,编译器似乎将参数视为Item* const &t,其读作为“对指向项目的const指针的引用”,这是一个不同的东西并且不会使{ {1}}指向不可变的。

我是否正确地解释了这一点?为什么编译器搞砸了,即使函数声明它不会改变参数?这真的是const语法等价可以搞砸的情况吗?为什么编译器使用后一种形式而不是前者?如果我想在包含器中存储指针并维护严格的const语义,我该怎么办呢?

1 个答案:

答案 0 :(得分:2)

在这种情况下,您可以使用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只是在容器中找到指针,而不是取消引用指针并改变另一方的指针。