Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Overload of operator[]

Reply
Thread Tools

Overload of operator[]

 
 
Adrian
Guest
Posts: n/a
 
      02-26-2008
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:perator[](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;
}
 
Reply With Quote
 
 
 
 
Victor Bazarov
Guest
Posts: n/a
 
      02-26-2008
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


 
Reply With Quote
 
 
 
 
Adrian
Guest
Posts: n/a
 
      02-26-2008
> 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
 
Reply With Quote
 
Bo Persson
Guest
Posts: n/a
 
      02-26-2008
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:perator[](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


 
Reply With Quote
 
John Gilson
Guest
Posts: n/a
 
      02-26-2008
On Feb 26, 7:55 am, Adrian <(E-Mail Removed)> 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:perator[](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>:perator[](i).

-- JAG
 
Reply With Quote
 
Adrian
Guest
Posts: n/a
 
      02-26-2008
On Feb 26, 10:48 am, "Bo Persson" <(E-Mail Removed)> 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
 
Reply With Quote
 
Bo Persson
Guest
Posts: n/a
 
      02-26-2008
Adrian wrote:
> On Feb 26, 10:48 am, "Bo Persson" <(E-Mail Removed)> 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


 
Reply With Quote
 
Adrian
Guest
Posts: n/a
 
      02-26-2008
On Feb 26, 1:44 pm, "Bo Persson" <(E-Mail Removed)> 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

 
Reply With Quote
 
James Kanze
Guest
Posts: n/a
 
      02-27-2008
On Feb 26, 9:44 pm, "Bo Persson" <(E-Mail Removed)> wrote:
> Adrian wrote:
> > On Feb 26, 10:48 am, "Bo Persson" <(E-Mail Removed)> 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:(E-Mail Removed)
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
 
Reply With Quote
 
Jerry Coffin
Guest
Posts: n/a
 
      03-01-2008
In article <05c563eb-2ac7-4ecd-a728-4666fcef28d1
@n75g2000hsh.googlegroups.com>, http://www.velocityreviews.com/forums/(E-Mail Removed) 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.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
function overload (not operator overload) Ying-Chieh Liao Perl Misc 3 10-11-2004 11:24 AM
UDP ports using PAT (NAT overload) - Help! Greg Grimes Cisco 8 10-08-2004 05:49 PM
UDP source ports using PAT (NAT overload) Greg Grimes Cisco 3 08-16-2004 10:26 PM
Using multiple outside interface with ip nat overload Emanuel Cisco 1 02-25-2004 08:10 AM
How use the overload of>> (or<<) of a class in the overload of << and >> of another class? Piotre Ugrumov C++ 3 01-25-2004 08:08 PM



Advertisments