开发者

Why can't I pass a const object in a const argument function/method?

EDIT:

Sorry, I'm trying to understand a sample of code, which uses QList::indexOf method, declared as in here.

Actually I'm trying to figure out why I need to use const_cast in this specific case:

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(con开发者_Go百科st_cast<ProjTreeItem*>(this)); 
    }
    return 0;
}

EDIT2:

I was looking at the wrong places, then I started to suspect that the issue had to do with the use of templates and the const modifier. I found this thread here. Please, look at Jon 's answer, which I think clarifies the point I reached. Sorry for the misleadings on my question.


I think you wanted this instead:

void SomeClass::f(const MyClass*) const
{ ... }


Hmmmm works for me with this code:

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;
}


You are making the wrong assumption that the type of item is equal to the type of this, and I believe this is confusing you.

Inside a const function, the type of this is ProjTreeItem const * const item. But your pointer that works is declared 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;

It helps to read the declaration right to left.

So, declare you item pointer like this and I suspect you'll need a cast as well.

const ProjTreeItem * const item = new ProjTreeItem(QList<QVariant>(), NULL);


I presume you mean the line

parentItem->childItems.indexOf(item);

doesn't compile. I also presume you wrote

QList< ProjTreeItem* > childItems;

in parentItem's type(class) definition.
If I understand correctly, in the line

parentItem->childItems.indexOf(item)

you are going to convert ProjTreeItem const* into ProjTreeItem*, and this requires const_cast.
JaredC has already answered kindly about constness. I suggest reading his answer again carefully.

Edit:
I think Jon's answer applies to your question.
The 1st parameter of QList::indexOf is T const&, where T is ProjTreeItem* in your case.
So, the concrete parameter type is ProjTreeItem*const&.
Please note it differs from ProjTreeItem const*const&.
ProjTreeItem* and ProjTreeItem const* are different types.
const_cast is needed to convert from the latter to the former.
ProjTreeItem const* means that ProjTreeItem is const.
However, ProjTreeItem*const& means pointer is const, ProjTreeItem is not const.

Edit2:
You seem to misunderstand.

#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;
}

If your interpretation is right, the above code will print true, and then false.
However, the code prints false, and then true.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜