const correctness - should C++ prefer const member over non-const?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • fungus

    #1

    const correctness - should C++ prefer const member over non-const?

    I define this class:


    class foo {
    std::vector<int >data;
    public:

    int operator[](int n) {
    return data[n];
    }
    int operator[](int n) const {
    return data[n];
    }
    };


    Now in my program I do:

    foo myFoo;
    int x = myFoo[123];
    ....


    Should the const version of foo::operator[] be called?

    I think it should, but my compiler disagrees with me.

    What's the correct behavior? Why...?



    --
    <\___/>
    / O O \
    \_____/ FTB.

    http://www.topaz3d.com/ - New 3D editor!
  • blargg

    #2
    Re: const correctness - should C++ prefer const member over non-const?

    In article
    <7908dabe-5102-4669-bf68-6cd36bedd6a7@m7 4g2000hsh.googl egroups.com>,
    fungus <openglMYSOCKS@ artlum.comwrote :
    I define this class:
    >
    >
    class foo {
    std::vector<int >data;
    public:
    >
    int operator[](int n) {
    return data[n];
    }
    int operator[](int n) const {
    return data[n];
    }
    };
    >
    >
    Now in my program I do:
    >
    foo myFoo;
    int x = myFoo[123];
    ...
    >
    >
    Should the const version of foo::operator[] be called?
    >
    I think it should, but my compiler disagrees with me.
    >
    What's the correct behavior? Why...?
    I'm interested in why you think it should call the const version. If it
    did, when would it ever call the non-const version?

    Comment

    • Jerry Coffin

      #3
      Re: const correctness - should C++ prefer const member over non-const?

      In article <7908dabe-5102-4669-bf68-6cd36bedd6a7
      @m74g2000hsh.go oglegroups.com> , openglMYSOCKS@a rtlum.com says...
      I define this class:
      >
      >
      class foo {
      std::vector<int >data;
      public:
      >
      int operator[](int n) {
      return data[n];
      }
      int operator[](int n) const {
      return data[n];
      }
      };
      >
      >
      Now in my program I do:
      >
      foo myFoo;
      int x = myFoo[123];
      ...
      >
      >
      Should the const version of foo::operator[] be called?
      No.
      I think it should, but my compiler disagrees with me.
      The compiler's right. The const version should be called for a const
      object. The non-const version should be called for a non-const object.
      If you don't/didn't have a non-const version, then the const version
      could be called -- but it would be called by convertion the non-const to
      a const object first. That's fine (in this case) but it's still a
      conversion. When matching overloaded functions, one that doesn't require
      a conversion is a better match than one that does require a conversion.

      Most people want the const version used on the RHS of an assignment, but
      the non-const for the LHS. To get what that kind of behavior, you
      normally use a proxy object that overloads operator= and operator T.

      --
      Later,
      Jerry.

      The universe is a figment of its own imagination.

      Comment

      • fungus

        #4
        Re: const correctness - should C++ prefer const member overnon-const?

        On Oct 30, 6:31 am, blargg....@gish puppy.com (blargg) wrote:
        >
        I'm interested in why you think it should call the const version. If it
        did, when would it ever call the non-const version?
        Ok, maybe I oversimplified it. Supposed operator[]
        returns a reference to the int:

        int& operator[](int n) {
        return data[n];
        }
        int& operator[](int n) const {
        return data[n];
        }

        If the expression is on the RHS of an assignment, should
        the const version be called?


        --
        <\___/>
        / O O \
        \_____/ FTB.

        http://www.topaz3d.com/ - New 3D editor!

        Comment

        • fungus

          #5
          Re: const correctness - should C++ prefer const member overnon-const?

          On Oct 30, 10:21 am, fungus <openglMYSO...@ artlum.comwrote :
          >
          Ok, maybe I oversimplified it. Supposed operator[]
          returns a reference to the int:
          >
          ....and just before the pedants arrive, suppose it's
          a struct not an int, and I want to access a member
          of the stuct.

          my_struct& operator[](int n) { return data[n]; }
          const my_struct& operator[](int n) const { return data[n]; }

          Why does the compiler choose the non-const version
          for the RHS of an expression...?


          --
          <\___/>
          / O O \
          \_____/ FTB.

          http://www.topaz3d.com/ - New 3D editor!

          Comment

          • anon

            #6
            Re: const correctness - should C++ prefer const member over non-const?

            fungus wrote:
            I define this class:
            >
            >
            class foo {
            std::vector<int >data;
            public:
            >
            int operator[](int n) {
            return data[n];
            Changing this line to this:
            return data.at(n);
            is much safer
            }
            int operator[](int n) const {
            return data[n];
            }
            };
            >
            >
            Now in my program I do:
            >
            foo myFoo;
            int x = myFoo[123];
            ...
            >
            This should call the non-const operator[]

            If you had:
            const foo myFoo;
            int x = myFoo[123];
            then the const version of the operator[] would be used
            >
            Should the const version of foo::operator[] be called?
            >
            I think it should, but my compiler disagrees with me.
            >
            What's the correct behavior? Why...?
            >

            Comment

            • anon

              #7
              Re: const correctness - should C++ prefer const member over non-const?

              fungus wrote:
              On Oct 30, 10:21 am, fungus <openglMYSO...@ artlum.comwrote :
              >Ok, maybe I oversimplified it. Supposed operator[]
              >returns a reference to the int:
              >>
              >
              ...and just before the pedants arrive, suppose it's
              a struct not an int, and I want to access a member
              of the stuct.
              >
              my_struct& operator[](int n) { return data[n]; }
              const my_struct& operator[](int n) const { return data[n]; }
              >
              Why does the compiler choose the non-const version
              for the RHS of an expression...?
              Because your myFoo object is not const

              Comment

              • fungus

                #8
                Re: const correctness - should C++ prefer const member overnon-const?

                On Oct 30, 6:41 am, Jerry Coffin <jcof...@taeus. comwrote:
                >
                Should the const version of foo::operator[] be called?
                >
                No.
                >
                I think it should, but my compiler disagrees with me.
                >
                The compiler's right.
                Bummer. I've got an object which triggers quite
                a big internal rebuild when you call the non-const
                version and I just noticed it's doing a lot of
                rebuilding because of this assumption.


                --
                <\___/>
                / O O \
                \_____/ FTB.

                http://www.topaz3d.com/ - New 3D editor!

                Comment

                • SG

                  #9
                  Re: const correctness - should C++ prefer const member overnon-const?

                  On 30 Okt., 10:59, fungus <openglMYSO...@ artlum.comwrote :
                  Bummer. I've got an object which triggers quite
                  a big internal rebuild when you call the non-const
                  version and I just noticed it's doing a lot of
                  rebuilding because of this assumption.
                  You can explicitly convert your object to a const version if you don't
                  want the non-const member function to be called in some cases:

                  const foo& myConstFoo = myFoo;
                  int blah = myConstFoo[42];

                  or something like that. static_cast<foo const&>(myFoo)[42] should also
                  work as far as I can tell. Though, these kinds of casts are still a
                  bit of a mystery to me.

                  Cheers,
                  SG

                  Comment

                  • blargg

                    #10
                    Re: const correctness - should C++ prefer const member over non-const?

                    In article
                    <8141ce63-f45b-4692-a05b-e6c44b367c7c@e1 7g2000hsg.googl egroups.com>,
                    fungus <openglMYSOCKS@ artlum.comwrote :
                    On Oct 30, 10:21=A0am, fungus <openglMYSO...@ artlum.comwrote :

                    Ok, maybe I oversimplified it. Supposed operator[]
                    returns a reference to the int:
                    >
                    ...and just before the pedants arrive, suppose it's
                    a struct not an int, and I want to access a member
                    of the stuct.
                    >
                    my_struct& operator[](int n) { return data[n]; }
                    const my_struct& operator[](int n) const { return data[n]; }
                    >
                    Why does the compiler choose the non-const version
                    for the RHS of an expression...?
                    That's a better question. It chooses the non-const version because C++
                    doesn't overload based on return type or how the caller uses the return
                    value, only arguments to the function (including the implicit "this"
                    argument to member functions). I could have sworn "The Design and
                    Evolution of C++" covered the reason behind this, but I couldn't find a
                    reference. I'm assuming it would complicate overloading and often not be
                    desired.

                    Comment

                    • blargg

                      #11
                      Re: const correctness - should C++ prefer const member over non-const?

                      In article
                      <bc2244bc-58cd-4e4e-bf20-3c66f04a4bb4@b1 g2000hsg.google groups.com>, SG
                      <s.gesemann@gma il.comwrote:
                      On 30 Okt., 10:59, fungus <openglMYSO...@ artlum.comwrote :
                      Bummer. I've got an object which triggers quite
                      a big internal rebuild when you call the non-const
                      version and I just noticed it's doing a lot of
                      rebuilding because of this assumption.
                      >
                      You can explicitly convert your object to a const version if you don't
                      want the non-const member function to be called in some cases:
                      >
                      const foo& myConstFoo = myFoo;
                      int blah = myConstFoo[42];
                      But you can't expect users of the class to do this consistently, since
                      it's quite tedious. Even having a named T& modify( int index ) would be
                      better. As others have mentioned, a proxy object with an operator T () and
                      operator = ( T const& ) would be most transparent to the user.

                      Comment

                      • fungus

                        #12
                        Re: const correctness - should C++ prefer const member overnon-const?

                        On Oct 30, 11:41 am, blargg....@gish puppy.com (blargg) wrote:
                        I could have sworn "The Design and Evolution of C++"
                        covered the reason behind this, but I couldn't find a
                        reference.
                        Maybe you mean section 3.7.1 ?


                        --
                        <\___/>
                        / O O \
                        \_____/ FTB.

                        http://www.topaz3d.com/ - New 3D editor!

                        Comment

                        • fungus

                          #13
                          Re: const correctness - should C++ prefer const member overnon-const?

                          On Oct 30, 11:45 am, blargg....@gish puppy.com (blargg) wrote:
                          As others have mentioned, a proxy object with an operator T () and
                          operator = ( T const& ) would be most transparent to the user.
                          I don't see how that works for a struct...

                          I want operator[] to return a reference to a struct
                          and be able to do this:

                          Foo f = myStuff[i].foo;

                          and

                          myStuff[i].foo = f;


                          With the first one calling the const version of operator[].



                          --
                          <\___/>
                          / O O \
                          \_____/ FTB.

                          http://www.topaz3d.com/ - New 3D editor!

                          Comment

                          • Martin Eisenberg

                            #14
                            Re: const correctness - should C++ prefer const member over non-const?

                            fungus wrote:
                            Bummer. I've got an object which triggers quite
                            a big internal rebuild when you call the non-const
                            version and I just noticed it's doing a lot of
                            rebuilding because of this assumption.
                            Then either the two methods' semantics are too different for a
                            single identifier, or the entity making the offending calls shouldn't
                            get its hands on a non-const reference, or you should memoize the
                            rebuilding method.


                            Martin

                            --
                            Quidquid latine scriptum est, altum videtur.

                            Comment

                            • fungus

                              #15
                              Re: const correctness - should C++ prefer const member overnon-const?

                              On Oct 30, 1:50 pm, Martin Eisenberg <martin.eisenb. ..@udo.eduwrote :
                              the entity making the offending calls shouldn't
                              get its hands on a non-const reference
                              >
                              This is probably the best solution. I need both const
                              and non const access inside an event handler function
                              so I guess I need to make the access more fine-grained.


                              --
                              <\___/>
                              / O O \
                              \_____/ FTB.

                              http://www.topaz3d.com/ - New 3D editor!

                              Comment

                              Working...