friend vs member for comparison operators

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

    friend vs member for comparison operators

    I've just encountered a strange situation (at least to me) regarding
    friend operators and member operators:

    #include <map>

    class Key
    {
    friend bool operator<(const Key& lhs, const Key& rhs)
    {
    return lhs.myInt < rhs.myInt;
    }

    public :
    Key(int i) : myInt(i) {}
    bool operator<(const Key& rhs)
    {
    return myInt < rhs.myInt;
    }

    private :
    int myInt;
    };

    int main()
    {
    std::map<Key, int> table; // Key must support operator<()
    table.insert(st d::make_pair(Ke y(1), 1));
    table.insert(st d::make_pair(Ke y(2), 2));
    return 0;
    }


    I assumed that friend operator<(const Key&, const Key&) and member
    operator operator<(const Key& rhs) are effectively the same thing, but
    the compiler (g++3) doesn't think so. Without the friend operator I
    get an error message like "cannot find match for const Key& < const
    Key&" generated within the std::map code, but it does say that Key <
    const Key& (the member operator) is a near match. Why can't the
    compiler treat a Key as a const Key& in this case?
  • Adam Fineman

    #2
    Re: friend vs member for comparison operators

    Michael Klatt wrote:[color=blue]
    > I've just encountered a strange situation (at least to me) regarding
    > friend operators and member operators:
    >[/color]
    The problem is not with friend vs. member functions, but with const vs.
    non-const member functions. (See below.)

    <snip>[color=blue]
    > bool operator<(const Key& rhs)[/color]
    bool operator<(const Key& rhs) const[color=blue]
    > {
    > return myInt < rhs.myInt;
    > }[/color]
    <snip>[color=blue]
    > Why can't the
    > compiler treat a Key as a const Key& in this case?[/color]

    It can, but only if you tell it to.

    HTH.

    - Adam

    --
    Reverse domain name to reply.

    Comment

    • lilburne

      #3
      Re: friend vs member for comparison operators

      Michael Klatt wrote:
      [color=blue]
      > I assumed that friend operator<(const Key&, const Key&) and member
      > operator operator<(const Key& rhs) are effectively the same thing, but
      > the compiler (g++3) doesn't think so. Without the friend operator I
      > get an error message like "cannot find match for const Key& < const
      > Key&" generated within the std::map code, but it does say that Key <
      > const Key& (the member operator) is a near match. Why can't the
      > compiler treat a Key as a const Key& in this case?[/color]

      What happens when you make operator<() const?

      Comment

      • Andrey Tarasevich

        #4
        Re: friend vs member for comparison operators

        Michael Klatt wrote:[color=blue]
        > I've just encountered a strange situation (at least to me) regarding
        > friend operators and member operators:
        >
        > #include <map>
        >
        > class Key
        > {
        > friend bool operator<(const Key& lhs, const Key& rhs)
        > {
        > return lhs.myInt < rhs.myInt;
        > }
        >
        > public :
        > Key(int i) : myInt(i) {}
        > bool operator<(const Key& rhs)
        > {
        > return myInt < rhs.myInt;
        > }
        >
        > private :
        > int myInt;
        > };
        >
        > int main()
        > {
        > std::map<Key, int> table; // Key must support operator<()
        > table.insert(st d::make_pair(Ke y(1), 1));
        > table.insert(st d::make_pair(Ke y(2), 2));
        > return 0;
        > }
        >
        >
        > I assumed that friend operator<(const Key&, const Key&) and member
        > operator operator<(const Key& rhs) are effectively the same thing, but
        > the compiler (g++3) doesn't think so. Without the friend operator I
        > get an error message like "cannot find match for const Key& < const
        > Key&" generated within the std::map code, but it does say that Key <
        > const Key& (the member operator) is a near match. Why can't the
        > compiler treat a Key as a const Key& in this case?[/color]

        According to the error message, the compiler is trying to compare two
        constant objects. Your member operator is not declared as 'const', which
        means that it cannot be called for a constant left-hand side object.
        Declare your member comparison operator as 'const'

        ...
        bool operator<(const Key& rhs) const
        ...

        and the code should compile.

        --
        Best regards,
        Andrey Tarasevich
        Brainbench C and C++ Programming MVP

        Comment

        • Michael Klatt

          #5
          Re: friend vs member for comparison operators

          Andrey Tarasevich <andreytarasevi ch@hotmail.com> wrote in message news:<vp8m70oog 5mt41@news.supe rnews.com>...[color=blue]
          > According to the error message, the compiler is trying to compare two
          > constant objects. Your member operator is not declared as 'const', which
          > means that it cannot be called for a constant left-hand side object.
          > Declare your member comparison operator as 'const'
          >
          > ...
          > bool operator<(const Key& rhs) const
          > ...
          >
          > and the code should compile.[/color]

          Oops, brain cramp, I wasn't thinking straight. Thanks for the suggestion everybody.

          Comment

          Working...