Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   C++ (http://www.velocityreviews.com/forums/f39-c.html)
-   -   Overload of operator[] (http://www.velocityreviews.com/forums/t594321-overload-of-operator.html)

Adrian 02-26-2008 03:55 PM

Overload of operator[]
 
I was trying to create a "readonly" operator[] in public scope and a
"write" operator[] in private scope of the class. But the compiler
seem intent on trying to use the private version.

Am I expecting to much from the compiler or is it not possible for it
to resolve the correct version of the function.

TIA

Adrian

dluadrianc:/home/adrianc> g++ -Wall -ansi -pedantic scope.cc
scope.cc: In function 'int main(int, char**)':
scope.cc:17: error: 'int& Container::operator[](size_t)' is private
scope.cc:31: error: within this context

#include <iostream>
#include <vector>

class Container : private std::vector<int>
{
public:
const int &operator[](size_t i) const
{
return (this->operator[](i));
}
using std::vector<int>::resize;
void set(size_t t, int i)
{
this->operator[](t)=i;
}
private:
int &operator[](size_t i)
{
return this->operator[](i);
}
};

int main(int argc, char *argv[])
{
Container a;

a.resize(10);
a.set(3,3);

std::cout << "Read test\n";
if(a[2]==3)
{
std::cout << "Its 3\n";
}
else
{
std::cout << "Its not 3\n";
}

return 0;
}

Victor Bazarov 02-26-2008 05:35 PM

Re: Overload of operator[]
 
Adrian wrote:
> I was trying to create a "readonly" operator[] in public scope and a
> "write" operator[] in private scope of the class. But the compiler
> seem intent on trying to use the private version.
>
> Am I expecting to much from the compiler or is it not possible for it
> to resolve the correct version of the function.
> [..]


Name resolution and overload resolution do not involve access
specifiers. Those are checked _after_ the resolution picked
the function. If the object is not const, the non-const member
function is called.

Now, which one should be used if you're inside another member
function, but this time it's a 'const' member function?

If you can answer that question, you can probably also give
your member functions different names (for example not use the
'operator[]' for the write-enabled stuff at all).

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask



Adrian 02-26-2008 05:41 PM

Re: Overload of operator[]
 
> Name resolution and overload resolution do not involve access
> specifiers. Those are checked _after_ the resolution picked
> the function. If the object is not const, the non-const member
> function is called.
>
> Now, which one should be used if you're inside another member
> function, but this time it's a 'const' member function?
>
> If you can answer that question, you can probably also give
> your member functions different names (for example not use the
> 'operator[]' for the write-enabled stuff at all).


Thanks Victor - that makes a lot of sense and is a workable solution
for me.

Trying to port a lot of old C array code without having to change too
much.


Adrian

Bo Persson 02-26-2008 05:48 PM

Re: Overload of operator[]
 
Adrian wrote:
> I was trying to create a "readonly" operator[] in public scope and a
> "write" operator[] in private scope of the class. But the compiler
> seem intent on trying to use the private version.
>
> Am I expecting to much from the compiler or is it not possible for
> it to resolve the correct version of the function.
>
> TIA
>
> Adrian
>
> dluadrianc:/home/adrianc> g++ -Wall -ansi -pedantic scope.cc
> scope.cc: In function 'int main(int, char**)':
> scope.cc:17: error: 'int& Container::operator[](size_t)' is private
> scope.cc:31: error: within this context
>
> #include <iostream>
> #include <vector>
>
> class Container : private std::vector<int>
> {
> public:
> const int &operator[](size_t i) const
> {
> return (this->operator[](i));
> }
> using std::vector<int>::resize;
> void set(size_t t, int i)
> {
> this->operator[](t)=i;
> }
> private:
> int &operator[](size_t i)
> {
> return this->operator[](i);
> }
> };
>
> int main(int argc, char *argv[])
> {
> Container a;
>
> a.resize(10);
> a.set(3,3);
>
> std::cout << "Read test\n";
> if(a[2]==3)
> {
> std::cout << "Its 3\n";
> }
> else
> {
> std::cout << "Its not 3\n";
> }
>
> return 0;
> }


It will call the const version of the operator for const containers,
and the non-const version for non-const containers. Only after
selecting the best fit for an operator or a function call, does the
compiler check for access rights. Oops, can't call it because it is
private!


Bo Persson



John Gilson 02-26-2008 06:07 PM

Re: Overload of operator[]
 
On Feb 26, 7:55 am, Adrian <bitbuc...@bluedreamer.com> wrote:
> I was trying to create a "readonly" operator[] in public scope and a
> "write" operator[] in private scope of the class. But the compiler
> seem intent on trying to use the private version.
>
> Am I expecting to much from the compiler or is it not possible for it
> to resolve the correct version of the function.
>
> TIA
>
> Adrian
>
> dluadrianc:/home/adrianc> g++ -Wall -ansi -pedantic scope.cc
> scope.cc: In function 'int main(int, char**)':
> scope.cc:17: error: 'int& Container::operator[](size_t)' is private
> scope.cc:31: error: within this context
>
> #include <iostream>
> #include <vector>
>
> class Container : private std::vector<int>
> {
> public:
> const int &operator[](size_t i) const
> {
> return (this->operator[](i));
> }
> using std::vector<int>::resize;
> void set(size_t t, int i)
> {
> this->operator[](t)=i;
> }
> private:
> int &operator[](size_t i)
> {
> return this->operator[](i);
> }
>
> };


In addition to the indicated access problem during member function
resolution, you have an infinite loop in your attempted call of
operator[] defined in the base class, i.e., you'd have to write
std::vector<int>::operator[](i).

-- JAG

Adrian 02-26-2008 06:25 PM

Re: Overload of operator[]
 
On Feb 26, 10:48 am, "Bo Persson" <b...@gmb.dk> wrote:
> It will call the const version of the operator for const containers,
> and the non-const version for non-const containers. Only after
> selecting the best fit for an operator or a function call, does the
> compiler check for access rights. Oops, can't call it because it is
> private!


I just assumed the compiler would know that this was a non modifying
call and check access before selecting functions. Although this is
probably possible I can see how this would be very hard to implement
in practice.


Adrian

Bo Persson 02-26-2008 08:44 PM

Re: Overload of operator[]
 
Adrian wrote:
> On Feb 26, 10:48 am, "Bo Persson" <b...@gmb.dk> wrote:
>> It will call the const version of the operator for const
>> containers, and the non-const version for non-const containers.
>> Only after selecting the best fit for an operator or a function
>> call, does the compiler check for access rights. Oops, can't call
>> it because it is private!

>
> I just assumed the compiler would know that this was a non modifying
> call and check access before selecting functions. Although this is
> probably possible I can see how this would be very hard to implement
> in practice.
>


Yes, the compiler cannot call different functions for a[2]==3 and
a[2]=3. Even if it did, it would be easy to save a reference to the
return value, and *perhaps* update it later. Then what?


Bo Persson



Adrian 02-26-2008 09:11 PM

Re: Overload of operator[]
 
On Feb 26, 1:44 pm, "Bo Persson" <b...@gmb.dk> wrote:
>Then what?

Thats when you get a nice core file that only happens on 3rd Tuesday
of each month when Dave didnt go to lunch and it was sunny today :-)


Adrian


James Kanze 02-27-2008 08:29 AM

Re: Overload of operator[]
 
On Feb 26, 9:44 pm, "Bo Persson" <b...@gmb.dk> wrote:
> Adrian wrote:
> > On Feb 26, 10:48 am, "Bo Persson" <b...@gmb.dk> wrote:
> >> It will call the const version of the operator for const
> >> containers, and the non-const version for non-const containers.
> >> Only after selecting the best fit for an operator or a function
> >> call, does the compiler check for access rights. Oops, can't call
> >> it because it is private!


> > I just assumed the compiler would know that this was a non modifying
> > call and check access before selecting functions. Although this is
> > probably possible I can see how this would be very hard to implement
> > in practice.


> Yes, the compiler cannot call different functions for a[2]==3 and
> a[2]=3.


It could in a different language. In C++, with one exception,
overload resolution doesn't take the context into consideration.
In practice, it would be impossible for it to do so because of
the large number of implicit conversions, and especially the
fact that everything converts to void---you can always legally
ignore the return value. But that's a characteristic of C++
(inherited from C).

> Even if it did, it would be easy to save a reference to the
> return value, and *perhaps* update it later.


If you save a reference to non-const, the non-const version is
called. If you save a reference to const, the const version.
That's one of the easier cases to define. Which function should
be called if you don't use the return value at all?

> Then what?


Dangling pointers and references are already part and parcel of
C++. One more more or less isn't going to change anything.

Note that it is possible to get the effect the original poster
wanted, by using a proxy.

--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Jerry Coffin 03-01-2008 04:42 PM

Re: Overload of operator[]
 
In article <05c563eb-2ac7-4ecd-a728-4666fcef28d1
@n75g2000hsh.googlegroups.com>, bitbucket@bluedreamer.com says...
> I was trying to create a "readonly" operator[] in public scope and a
> "write" operator[] in private scope of the class. But the compiler
> seem intent on trying to use the private version.
>
> Am I expecting to much from the compiler or is it not possible for it
> to resolve the correct version of the function.


You might want to read _More Effective C++_, around items 29 and 30. It
gives a fairly detailed explanation of how to handle this situation
using a proxy class.

--
Later,
Jerry.

The universe is a figment of its own imagination.


All times are GMT. The time now is 06:05 PM.

Powered by vBulletin®. Copyright ©2000 - 2013, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.