const functions problems...

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

    const functions problems...

    How can I avoid writting and maintaining the same code in the two operator
    [] implementation below? I know that in the minimal example below, the
    implementation is trivial, but I found this type of problem (maintaining two
    function overloads one const and one not const - having the same body), many
    times...

    Thanks,
    Romulus


    #include <iostream>

    class SomeClass
    {
    public:
    int & operator[](int index)
    {
    return array[index];
    }

    const int & operator[](int index) const
    {
    return array[index];
    }

    protected:
    // internal data
    int array[10];
    };

    void func(const SomeClass & sc, int index)
    {
    std::cout << sc[index] << std::endl;
    }

    void main(void)
    {
    SomeClass c;
    c[3] = 5;
    func(c, 3);
    }


  • John Harrison

    #2
    Re: const functions problems...


    "Romulus Mare" <modeleromy_no_ spam@yahoo.com> wrote in message
    news:bh6ba6$uio j9$1@ID-1317.news.uni-berlin.de...[color=blue]
    > How can I avoid writting and maintaining the same code in the two operator
    > [] implementation below? I know that in the minimal example below, the
    > implementation is trivial, but I found this type of problem (maintaining[/color]
    two[color=blue]
    > function overloads one const and one not const - having the same body),[/color]
    many[color=blue]
    > times...
    >
    > Thanks,
    > Romulus
    >[/color]

    Sometimes an option is to use a const_cast, so the const version calls the
    non-const version. This is legit provided the non-const version doesn't
    modify the object during its execution (which is often the case).

    class X
    {
    const int& func() const { return const_cast<X*>( this)->func(); }
    int& func()
    {
    ...
    }
    };

    john


    Comment

    • Romulus Mare

      #3
      Re: const functions problems...

      [color=blue]
      > Sometimes an option is to use a const_cast, so the const version calls the
      > non-const version. This is legit provided the non-const version doesn't
      > modify the object during its execution (which is often the case).
      >
      > class X
      > {
      > const int& func() const { return const_cast<X*>( this)->func(); }
      > int& func()
      > {
      > ...
      > }
      > };
      >[/color]

      Thanks, John...

      So, if I understood correctly, I am facing one of the following very
      dangerous solutions:

      1. Maintain the same code in two functions: one const and one not const
      - OR -
      2. Accept to work with the compiler not checking of constness in "non const"
      int& func(). I know, the code is the same and should not do any
      modifications in class, but this is no more elegant than old-style C cast...

      Any other options for solving such issues?

      Romulus


      Comment

      • Rolf Magnus

        #4
        Re: const functions problems...

        Romulus Mare wrote:
        [color=blue]
        > How can I avoid writting and maintaining the same code in the two
        > operator
        > [] implementation below? I know that in the minimal example below, the
        > implementation is trivial, but I found this type of problem
        > (maintaining two function overloads one const and one not const -
        > having the same body), many times...[/color]

        I've seen people making use of const_cast for this (the only place I
        know where it isn't a guaranteed sign for an error).
        [color=blue]
        > #include <iostream>
        >
        > class SomeClass
        > {
        > public:
        > int & operator[](int index)
        > {
        > return array[index];
        > }
        >
        > const int & operator[](int index) const
        > {
        > return array[index];
        > }[/color]

        const int & operator[](int index) const
        {
        return const_cast<Some Class*>(this)->operator[](index);
        }

        With this, you don't need to maintain two copies of the implementation.
        Of course, you shouldn't modify the object in that implemention.
        [color=blue]
        > protected:
        > // internal data
        > int array[10];
        > };
        >
        > void func(const SomeClass & sc, int index)
        > {
        > std::cout << sc[index] << std::endl;
        > }
        >
        > void main(void)[/color]

        main _must_ return int.
        [color=blue]
        > {
        > SomeClass c;
        > c[3] = 5;
        > func(c, 3);
        > }[/color]

        Comment

        • John Harrison

          #5
          Re: const functions problems...


          "Romulus Mare" <modeleromy_no_ spam@yahoo.com> wrote in message
          news:bh6dlp$ta0 7k$1@ID-1317.news.uni-berlin.de...[color=blue]
          >[color=green]
          > > Sometimes an option is to use a const_cast, so the const version calls[/color][/color]
          the[color=blue][color=green]
          > > non-const version. This is legit provided the non-const version doesn't
          > > modify the object during its execution (which is often the case).
          > >
          > > class X
          > > {
          > > const int& func() const { return const_cast<X*>( this)->func(); }
          > > int& func()
          > > {
          > > ...
          > > }
          > > };
          > >[/color]
          >
          > Thanks, John...
          >
          > So, if I understood correctly, I am facing one of the following very
          > dangerous solutions:
          >
          > 1. Maintain the same code in two functions: one const and one not const
          > - OR -
          > 2. Accept to work with the compiler not checking of constness in "non[/color]
          const"[color=blue]
          > int& func(). I know, the code is the same and should not do any
          > modifications in class, but this is no more elegant than old-style C[/color]
          cast...[color=blue]
          >
          > Any other options for solving such issues?
          >
          > Romulus
          >[/color]

          None that immediately spring to mind. Normally I find that such functions
          are more or less one liners (as was your example), so the issue of
          maintaining two identical functions doesn't really arise.

          Perhaps if you could give some specific examples that you are concerned
          about then someone might suggest some other possibilities.

          john


          Comment

          • Sam Holden

            #6
            Re: const functions problems...

            On Mon, 11 Aug 2003 00:32:36 +0300,
            Romulus Mare <modeleromy_no_ spam@yahoo.com> wrote:[color=blue]
            >[color=green]
            >> Sometimes an option is to use a const_cast, so the const version calls the
            >> non-const version. This is legit provided the non-const version doesn't
            >> modify the object during its execution (which is often the case).
            >>
            >> class X
            >> {
            >> const int& func() const { return const_cast<X*>( this)->func(); }
            >> int& func()
            >> {
            >> ...
            >> }
            >> };
            >>[/color]
            >
            > Thanks, John...
            >
            > So, if I understood correctly, I am facing one of the following very
            > dangerous solutions:
            >
            > 1. Maintain the same code in two functions: one const and one not const
            > - OR -
            > 2. Accept to work with the compiler not checking of constness in "non const"
            > int& func(). I know, the code is the same and should not do any
            > modifications in class, but this is no more elegant than old-style C cast...
            >
            > Any other options for solving such issues?[/color]

            Put the code in the const function, and const_cast to a const pointer and
            call that function from the non-const function?

            Add a third const function containing the implementation which is called
            by both versions of func()?

            --
            Sam Holden

            Comment

            • Romulus Mare

              #7
              Re: const functions problems...

              [color=blue]
              > None that immediately spring to mind. Normally I find that such functions
              > are more or less one liners (as was your example), so the issue of
              > maintaining two identical functions doesn't really arise.[/color]

              Well, unfortunately mine are not quite large but surely not one-liners.
              [color=blue]
              > Perhaps if you could give some specific examples that you are concerned
              > about then someone might suggest some other possibilities.[/color]

              Cannot do it. The project and dependencies are quite large for a post in a
              news group. This is why I tried to simplify the original posted code.
              [color=blue]
              > john
              >
              >[/color]


              Comment

              • Romulus Mare

                #8
                Re: const functions problems...

                [color=blue]
                > Put the code in the const function, and const_cast to a const pointer and
                > call that function from the non-const function?[/color]

                How can I do this? const_case removes constness, is it not?
                [color=blue]
                > Add a third const function containing the implementation which is called
                > by both versions of func()?[/color]

                Yes, but the problems remains the same. Working with const functions as not
                const functions... Still old C style cast equivalent solution...
                [color=blue]
                > --
                > Sam Holden
                >[/color]

                Thanks.


                Comment

                • Sam Holden

                  #9
                  Re: const functions problems...

                  On Mon, 11 Aug 2003 01:05:50 +0300,
                  Romulus Mare <modeleromy_no_ spam@yahoo.com> wrote:[color=blue]
                  >[color=green]
                  >> Put the code in the const function, and const_cast to a const pointer and
                  >> call that function from the non-const function?[/color]
                  >
                  > How can I do this? const_case removes constness, is it not?[/color]

                  Possibly, I posted before I'd drunk my morning coffee, and the casting
                  part of C++ is something I am very unfamiliar with.

                  class A {
                  public:
                  int foo() const {return 10;}
                  int foo() {return const_cast<cons t A*>(this)->foo();}
                  };

                  compiles for me, but my compiler laughs at the standard and hence that
                  doesn't mean much.

                  If that isn't allowed (and someone will say so I'm sure :) then why not:

                  class A {
                  public:
                  int foo() const {return 10;}
                  int foo() {return static_cast<con st A*>(this)->foo();}
                  };

                  [Note, I suspect I came in late on the thread, so sorry if I'm repeating
                  discounted solution, or misinterpreting the issue]
                  [color=blue]
                  >[color=green]
                  >> Add a third const function containing the implementation which is called
                  >> by both versions of func()?[/color]
                  >
                  > Yes, but the problems remains the same. Working with const functions as not
                  > const functions... Still old C style cast equivalent solution...[/color]

                  I don't understand that statement, but then again the morning coffee hasn't
                  kicked in yet (though it has now been consumed). The non-const function
                  would call the const helper function, that's fine and dandy :)

                  --
                  Sam Holden

                  Comment

                  • Cy Edmunds

                    #10
                    Re: const functions problems...

                    "Romulus Mare" <modeleromy_no_ spam@yahoo.com> wrote in message
                    news:bh6ba6$uio j9$1@ID-1317.news.uni-berlin.de...[color=blue]
                    > How can I avoid writting and maintaining the same code in the two operator
                    > [] implementation below? I know that in the minimal example below, the
                    > implementation is trivial, but I found this type of problem (maintaining[/color]
                    two[color=blue]
                    > function overloads one const and one not const - having the same body),[/color]
                    many[color=blue]
                    > times...
                    >
                    > Thanks,
                    > Romulus
                    >
                    >
                    > #include <iostream>
                    >
                    > class SomeClass
                    > {
                    > public:
                    > int & operator[](int index)
                    > {
                    > return array[index];
                    > }
                    >
                    > const int & operator[](int index) const
                    > {
                    > return array[index];
                    > }
                    >
                    > protected:
                    > // internal data
                    > int array[10];
                    > };
                    >
                    > void func(const SomeClass & sc, int index)
                    > {
                    > std::cout << sc[index] << std::endl;
                    > }
                    >
                    > void main(void)
                    > {
                    > SomeClass c;
                    > c[3] = 5;
                    > func(c, 3);
                    > }
                    >[/color]

                    C++ has a keyword "mutable" which might be applicable to your situation --
                    I can't tell from the information revealed by your post. In principle it
                    avoids a const_cast in some situations, but now you have an implicit
                    const_cast every time you use it. I have never actually used "mutable"
                    myself.

                    BTW, I wouldn't agree that a const_cast is quite as bad as an old style C
                    cast. The C cast is more dangerous because it is more powerful. I think that
                    given that you want to cheat the system a little I think you will probably
                    have to own up to a const_cast someplace.

                    --
                    Cy



                    Comment

                    • Rolf Magnus

                      #11
                      Re: const functions problems...

                      Romulus Mare wrote:
                      [color=blue]
                      >[color=green]
                      >> Put the code in the const function, and const_cast to a const pointer
                      >> and call that function from the non-const function?[/color]
                      >
                      > How can I do this? const_case removes constness, is it not?[/color]

                      Yes, but you could instead static_cast the this pointer into a const
                      pointer, and then const_cast the returned reference.
                      [color=blue][color=green]
                      >> Add a third const function containing the implementation which is
                      >> called by both versions of func()?[/color]
                      >
                      > Yes, but the problems remains the same. Working with const functions
                      > as not const functions... Still old C style cast equivalent
                      > solution...[/color]

                      Well, I'm afraid you have to live with the code duplication then.

                      Comment

                      • tom_usenet

                        #12
                        Re: const functions problems...

                        On Mon, 11 Aug 2003 00:32:36 +0300, "Romulus Mare"
                        <modeleromy_no_ spam@yahoo.com> wrote:
                        [color=blue]
                        >[color=green]
                        >> Sometimes an option is to use a const_cast, so the const version calls the
                        >> non-const version. This is legit provided the non-const version doesn't
                        >> modify the object during its execution (which is often the case).
                        >>
                        >> class X
                        >> {
                        >> const int& func() const { return const_cast<X*>( this)->func(); }
                        >> int& func()
                        >> {
                        >> ...
                        >> }
                        >> };
                        >>[/color]
                        >
                        >Thanks, John...
                        >
                        >So, if I understood correctly, I am facing one of the following very
                        >dangerous solutions:
                        >
                        >1. Maintain the same code in two functions: one const and one not const
                        > - OR -
                        >2. Accept to work with the compiler not checking of constness in "non const"
                        >int& func(). I know, the code is the same and should not do any
                        >modification s in class, but this is no more elegant than old-style C cast...[/color]

                        Either you have to accept that the const version and non-const version
                        are different operations, and implement them separately, or you have
                        to accept that they are the same operation, and use the const cast.
                        You can't have it both ways...
                        [color=blue]
                        >Any other options for solving such issues?[/color]

                        A non-member template friend function might do the trick (one
                        instantiation for const T, one for non-const T), but that would be
                        crazy.

                        I suppose it would be nice to be able to template on cv-qualification
                        for template members. e.g.

                        class X
                        {
                        public:
                        template <cv qualifiers>
                        Y qualifiers& func() qualifiers;
                        };

                        //implement in cpp file.
                        //explicitly instantiate for no cv and for const.

                        However, I don't think it is useful enough to be worth adding to the
                        language, since it adds yet more headaches to argument deduction and
                        overloading.

                        Tom

                        Comment

                        Working...