Почему я не могу передать const-объект в функцию / метод const-аргумента? - PullRequest
1 голос
/ 19 января 2011

EDIT:

Извините, я пытаюсь понять пример кода, который использует метод QList::indexOf, объявленный как в здесь .

На самом деле я пытаюсь выяснить, почему мне нужно использовать const_cast в данном конкретном случае:

int ProjTreeItem::row() const
{
    if (parentItem) {
            // instance of const object to test  
        const ProjTreeItem *item = new ProjTreeItem(QList<QVariant>(), NULL); 
            // Called indexOf here to test
        parentItem->childItems.indexOf(item); 
            // This works fine
        return parentItem->childItems.indexOf(const_cast<ProjTreeItem*>(this)); 
    }
    return 0;
}

EDIT2:

Я искал не те места, а потом начал подозревать, что проблема связана с использованием шаблонов и модификатора const. Я нашел эту тему здесь . Пожалуйста, посмотрите на ответ Джона, который, я думаю, проясняет точку, которой я достиг. Извините за заблуждения по моему вопросу.

Ответы [ 4 ]

3 голосов
/ 19 января 2011

Я думаю, что вы хотели это вместо:

void SomeClass::f(const MyClass*) const
{ ... }
2 голосов
/ 19 января 2011

Хммм работает у меня с этим кодом:

class MyClass
{
};

class SomeClass 
{
public:
    void f(const MyClass *t) const
    {
    }
};

int main()
{
    SomeClass s;

    const MyClass *myClass = new MyClass;
    MyClass *myClass2 = new MyClass;

    s.f(myClass);
    s.f(myClass2);

    return 0;
}
1 голос
/ 19 января 2011

Вы ошибочно полагаете, что тип item равен типу this, и я считаю, что это вас смущает.

Внутри функции const тип this равен ProjTreeItem const * const item. Но ваш указатель, который работает, объявлен const ProjTreeItem * item:

// `this` is a constant-pointer-to-a-constant-ProjTreeItem
ProjTreeItem const * const this;   // obviously not valid code, just illustrating type

// `item` is simply a pointer-to-a-constant-ProjTreeItem
const ProjTreeItem * item;

Помогает прочитать декларацию справа налево.

Итак, объявите указатель предмета следующим образом, и я подозреваю, что вам также понадобится приведение.

const ProjTreeItem * const item = new ProjTreeItem(QList<QVariant>(), NULL);
0 голосов
/ 19 января 2011

Полагаю, вы имеете в виду линию

parentItem->childItems.indexOf(item);

не компилируется. Я также предполагаю, что вы написали

QList< ProjTreeItem* > childItems;

в определении типа (класса) parentItem.
Если я правильно понимаю, в строке

parentItem->childItems.indexOf(item)

вы собираетесь конвертировать ProjTreeItem const* в ProjTreeItem*, и для этого требуется const_cast.
JaredC уже любезно ответил о константности. Я предлагаю внимательно прочитать его ответ.

Edit:
Я думаю, что ответ Джона относится к вашему вопросу.
1-й параметр QList::indexOf равен T const&, где T равен ProjTreeItem* в вашем случае.
Итак, конкретный тип параметра: ProjTreeItem*const&.
Обратите внимание, что он отличается от ProjTreeItem const*const&.
ProjTreeItem* и ProjTreeItem const* - это разные типы.
const_cast необходимо для преобразования из последнего в первое.
ProjTreeItem const* означает, что ProjTreeItem равно const.
Однако ProjTreeItem*const& означает , указатель равен const, ProjTreeItem равен , а не const.

Edit2
Вы, кажется, неправильно поняли.

#include <typeinfo>
#include <iostream>
using namespace std;

struct ProjTreeItem;

template< class T >
struct Test {
  typedef T const type;
};

int main()
{
  cout<< boolalpha;
  cout<<
    (typeid( Test< ProjTreeItem* >::type ) == typeid( ProjTreeItem const* ))
  <<endl;
  cout<<
    (typeid( Test< ProjTreeItem* >::type ) == typeid( ProjTreeItem*const ))
  <<endl;
}

Если ваша интерпретация верна, приведенный выше код напечатает true, а затем false.
Однако код печатает false, а затем true.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...