Overload of operator[]

Discussion in 'C++' started by Adrian, Feb 26, 2008.

  1. Adrian

    Adrian Guest

    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;
    }
    Adrian, Feb 26, 2008
    #1
    1. Advertising

  2. 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
    Victor Bazarov, Feb 26, 2008
    #2
    1. Advertising

  3. Adrian

    Adrian Guest

    > 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
    Adrian, Feb 26, 2008
    #3
  4. Adrian

    Bo Persson Guest

    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::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
    Bo Persson, Feb 26, 2008
    #4
  5. Adrian

    John Gilson Guest

    On Feb 26, 7:55 am, 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::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
    John Gilson, Feb 26, 2008
    #5
  6. Adrian

    Adrian Guest

    On Feb 26, 10:48 am, "Bo Persson" <> 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
    Adrian, Feb 26, 2008
    #6
  7. Adrian

    Bo Persson Guest

    Adrian wrote:
    > On Feb 26, 10:48 am, "Bo Persson" <> 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
    Bo Persson, Feb 26, 2008
    #7
  8. Adrian

    Adrian Guest

    On Feb 26, 1:44 pm, "Bo Persson" <> 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
    Adrian, Feb 26, 2008
    #8
  9. Adrian

    James Kanze Guest

    On Feb 26, 9:44 pm, "Bo Persson" <> wrote:
    > Adrian wrote:
    > > On Feb 26, 10:48 am, "Bo Persson" <> 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:
    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
    James Kanze, Feb 27, 2008
    #9
  10. Adrian

    Jerry Coffin Guest

    In article <05c563eb-2ac7-4ecd-a728-4666fcef28d1
    @n75g2000hsh.googlegroups.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.
    Jerry Coffin, Mar 1, 2008
    #10
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Mr Smith
    Replies:
    7
    Views:
    463
    Mr Smith
    Feb 10, 2005
  2. Matthew Monopole

    overload operator -

    Matthew Monopole, Aug 8, 2003, in forum: C++
    Replies:
    1
    Views:
    474
    Jakob Bieling
    Aug 8, 2003
  3. Jakob Bieling

    Q: Overload operator new/delete

    Jakob Bieling, Aug 8, 2003, in forum: C++
    Replies:
    0
    Views:
    398
    Jakob Bieling
    Aug 8, 2003
  4. Piotre Ugrumov
    Replies:
    3
    Views:
    368
    Nick Hounsome
    Jan 25, 2004
  5. Ying-Chieh Liao

    function overload (not operator overload)

    Ying-Chieh Liao, Oct 11, 2004, in forum: Perl Misc
    Replies:
    3
    Views:
    248
    Sherm Pendley
    Oct 11, 2004
Loading...

Share This Page