Overload of operator[]

A

Adrian

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::eek: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;
}
 
V

Victor Bazarov

Adrian said:
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
 
A

Adrian

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
 
B

Bo Persson

Adrian said:
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::eek: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
 
J

John Gilson

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::eek: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>::eek:perator[](i).

-- JAG
 
A

Adrian

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
 
B

Bo Persson

Adrian said:
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
 
J

James Kanze

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.
 
J

Jerry Coffin

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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,764
Messages
2,569,564
Members
45,039
Latest member
CasimiraVa

Latest Threads

Top