Method overloading with const/non-const variants (was: Re: KDE/kdelibs/kdecore)

Friedrich W. H. Kossebau kossebau at kde.org
Tue Jul 8 11:39:30 BST 2008


Am Dienstag, 8. Juli 2008, um 10:05 Uhr, schrieb David Faure:
> On Tuesday 08 July 2008, Andreas Pakulat wrote:
> > On 07.07.08 23:19:59, Thiago Macieira wrote:
> > > Andreas Pakulat wrote:
> > > >I'm not sure why the const_this is needed here anyway, shouldn't a
> > > > simple const_iterator and ::constEnd() be sufficient too?
> > >
> > > It's needed because of the missing constFind() function. There are two
> > > overloads to find(): one non-const returning an iterator and a const
> > > returning a const_iterator. The only way to select the const version
> > > (and hence avoid detaching) is to have a const container.
> >
> > aah, I thought the compiler was clever enough to use the const-version
> > when I'm doing
> >
> > QHash<Foo,Bar>::const_iterator it = somemap.find();
> >
> > Due to the needed const-type on the left hand side.
>
> No, because the RHS is evaluated first, and then that iterator can be
> converted to a const_iterator. This is also the reason why
> constBegin/constEnd exist in the first place.

<C++ seminar>
What about overloaded methods? Hm, running the test from below shows me that I 
have been thinking wrong for many years, duh. So the compiler chooses the 
variant by the constness of the object? I thought it takes all possible 
variants and then narrows the selection further by the LHS, going for 
constness if possible?

Is this defined by the C++ specs? Does anyone know the rationale behind this?

--- 8< ---
#include <iostream>

class K
{
  public:
    explicit K( char *data );
  public:
    char *data();
    const char *data() const;

  protected:
    char *mData;
};

K::K( char *data ) : mData( data ) {}

char *K::data()
{
    std::cout << "using non-const data()"<<std::endl;
    return mData;
}

const char *K::data() const
{
    std::cout << "using const data()"<<std::endl;
    return mData;
}


int main()
{
    char *data = new char[2];
    data[0] = 'K'; data[1] = 0;

    const K constK( data );
    K nonconstK( data );

    const char *dataFromConstK = constK.data();
    std::cout <<"dataFromConstK: "<< dataFromConstK << std::endl;

    const char *dataFromNonConstK = nonconstK.data();
    std::cout <<"dataFromNonConstK: "<< dataFromNonConstK << std::endl;

    delete [] data;
}
--- 8< ---
Result:
> ./test
using const data()
dataFromConstK: K
using non-const data()
dataFromNonConstK: K

Cheers
Friedrich

-- 
Okteta - KDE Hex Editor, coming to you with KDE 4.1




More information about the kde-core-devel mailing list