const and non-const operator[] Vs. lvalue and rvalue use

Discussion in 'C++' started by Mark Stijnman, Apr 22, 2005.

  1. I would like to be able to have an object accessible as a vector using
    the [] operator, but able to track modifications to its data, so that
    it can update other internal data as needed. I figured that setting a
    flag in the non-const operator[] would work, but it doesn't. Take the
    code below:

    #include <iostream>

    using std::cout;
    using std::cerr;
    using std::endl;

    class Test {
    public:
    Test() {
    for (int i=0; i<4; i++) t = 1.0;
    }

    const double& operator[](const unsigned index) const {
    cerr << "const operator called" << endl;
    return t[index];
    }
    double& operator[](const unsigned index) {
    cerr << "non-const operator called" << endl;
    return t[index];
    }
    private:
    double t[4];
    };

    int main() {
    Test t;

    t[2] = 2; // #1
    cout << "t[2] = " << t[2] << endl; // #2
    t[3] += t[2] + t[1]; // #3
    cout << "t[3] = " << t[3] << endl; // #4
    }

    I personally expected it to use the non-const version in the lines
    marked #1 and #3, where it uses t as an lvalue, and use the const
    version when t is used as an rvalue, like in lines #2, the right
    hand side of #3, and in line #4. Unfortunately, on my system, when run,
    it appears only the non-const operator gets called. Apparantly that's
    not how it works. How are the rules here defined? And how do I get the
    behaviour I want (i.e., different versions called, depending on use as
    an lvalue or not)?

    regards Mark
     
    Mark Stijnman, Apr 22, 2005
    #1
    1. Advertising

  2. Mark Stijnman wrote:
    > I would like to be able to have an object accessible as a vector using
    > the [] operator, but able to track modifications to its data, so that
    > it can update other internal data as needed. I figured that setting a
    > flag in the non-const operator[] would work, but it doesn't. Take the
    > code below:
    >
    > #include <iostream>
    >
    > using std::cout;
    > using std::cerr;
    > using std::endl;
    >
    > class Test {
    > public:
    > Test() {
    > for (int i=0; i<4; i++) t = 1.0;
    > }
    >
    > const double& operator[](const unsigned index) const {
    > cerr << "const operator called" << endl;
    > return t[index];
    > }
    > double& operator[](const unsigned index) {
    > cerr << "non-const operator called" << endl;
    > return t[index];
    > }
    > private:
    > double t[4];
    > };
    >
    > int main() {
    > Test t;
    >
    > t[2] = 2; // #1
    > cout << "t[2] = " << t[2] << endl; // #2
    > t[3] += t[2] + t[1]; // #3
    > cout << "t[3] = " << t[3] << endl; // #4
    > }
    >
    > I personally expected it to use the non-const version in the lines
    > marked #1 and #3, where it uses t as an lvalue, and use the const
    > version when t is used as an rvalue, like in lines #2, the right
    > hand side of #3, and in line #4. Unfortunately, on my system, when run,
    > it appears only the non-const operator gets called. Apparantly that's
    > not how it works. How are the rules here defined?


    That's extremely simple. 't' (for which operator[] is called) is not
    a const object. For a non-const object a non-const version is called.

    > And how do I get the
    > behaviour I want (i.e., different versions called, depending on use as
    > an lvalue or not)?


    You can't (not easily, anyway). The return value type is not the deciding
    factor in the process of picking which overloaded function to call.

    V
     
    Victor Bazarov, Apr 22, 2005
    #2
    1. Advertising

  3. Mark Stijnman wrote:

    > I would like to be able to have an object accessible as a vector using
    > the [] operator, but able to track modifications to its data, so that
    > it can update other internal data as needed. I figured that setting a
    > flag in the non-const operator[] would work, but it doesn't. Take the


    You can return some type of proxy object in the non const operator [ ], and
    in this object have an operator = that sets the modified flag corresponding
    to the item it refers to.

    --
    Salu2
     
    =?ISO-8859-15?Q?Juli=E1n?= Albo, Apr 22, 2005
    #3
    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. Gonzalo Aguirre

    rvalue / lvalue operator[]

    Gonzalo Aguirre, Jan 2, 2004, in forum: C++
    Replies:
    4
    Views:
    466
    Ron Natalie
    Jan 2, 2004
  2. Kavya
    Replies:
    9
    Views:
    542
    Dik T. Winter
    Oct 28, 2006
  3. Andrew Ward
    Replies:
    2
    Views:
    1,108
    Zorro
    Jul 19, 2005
  4. jimjim

    lvalue (s) and rvalue (s)

    jimjim, Mar 25, 2006, in forum: C++
    Replies:
    7
    Views:
    415
    Kai-Uwe Bux
    Mar 26, 2006
  5. Juha Nieminen
    Replies:
    13
    Views:
    656
    Edek Pienkowski
    Aug 29, 2012
Loading...

Share This Page