Thread: Overloaded a struct operator==

  1. #1
    Programming Ninja In-T...
    Join Date
    May 2009
    Posts
    827

    Unhappy Overloaded a struct operator==

    Inside my struct called "S_html_attr_value", I have overloaded the == operator, using the following code:

    Code:
    bool operator== (const S_html_attr_value& attrValue) {
            if (attrValue.content == this->content) {
               return true;
            }
    
            return false;
    }
    Now, I attempted to make use of it using the following code:

    Code:
    for (attr_values_iterator it = ATTR_NAME.supported_attr_values.begin();
          it != ATTR_NAME.supported_attr_values.end(); it++) {
         for (size_t i = 0; i < it->second.size(); i++) {
              if (it->second.at(i) == attrValue) {
                 attr_value_is_supported = true;
                 break;
              }
         }
         if (attr_value_is_supported)
            break;
    }
    where "ATTR_NAME" is to be replaced with a given attribute's name (i.e. I don't actually use that in the code). attr_values_iterator is a typedef for a map<S_browser, TYPE_attr_values>::const_iterator. TYPE_attr_values is a typedef for a vector<S_html_attr_value>. So essentially, what I'm doing in the code is using a map iterator to iterate through the map, and then for each map element, I iterate through it->second (which is a vector, of course). I compare it->second.at(i) (which is either a const_reference S_html_attr_value, or a reference S_html_attr_value, depending on which at() function is being called of the vector) with attrValue which is a const S_html_attr_value&.

    Therefore, I do not understand the compile error that I get for the red text which says the following:
    error: passing ‘const S_html_attr_value’ as ‘this’ argument of ‘bool S_html_attr_value::operator==(const S_html_attr_value&)’ discards qualifiers
    Why is this invalid?
    Last edited by Programmer_P; 03-03-2011 at 08:28 PM.
    I'm an alien from another world. Planet Earth is only my vacation home, and I'm not liking it.

  2. #2
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    If at() is a const method, then it would make sense, because technically you are using the result of at() in a method which as far as the compiler can tell changes the object on which at() is being used. Another equally possible answer is both are const and you are using a non-const method, anyway.

    operator== is usually implemented as a free function with both parameters const, so if you don't do that, at least make the method const to enforce similar behavior.
    Last edited by whiteflags; 03-03-2011 at 09:07 PM.

  3. #3
    Programming Ninja In-T...
    Join Date
    May 2009
    Posts
    827
    Quote Originally Posted by whiteflags View Post
    If at() is a const method, then it would make sense, because technically you are using the result of at() in a method which as far as the compiler can tell changes the object on which at() is being used. Another equally possible answer is both are const and you are using a non-const method, anyway.
    Yeah, I guess I don't understand 'const'...
    I spent the last several minutes looking at this link, which explains what the C++ 'const' declaration is, and some of its drawbacks are, but I'm afraid it left me even more confused. For one thing, I always assumed that having a const& parameter in a function means passing an object by reference, instead of by copy, and putting a restriction on modifying what's being referenced inside the function it was passed to. However, the guy who wrote the page talks about the meaning of 'const' changing depending on where its placed in relation to the rest of a pointer's declaration. He says code like "const int* p" means a variable pointer pointing to a const integer, and "int* const p" on the other hand is a const pointer pointing to a variable integer, and "int const* const p" is a const pointer to a const integer.
    He does not however explain adequately enough what the full implications of the 'const' keyword with references are. For example, he says that to pass an object by reference where it can't be modifed, one has to use the syntax "OBJECT_TYPE& const OBJECT_NAME", i.e. with the 'const' keyword after the '&'., and then later says:
    An object which has been made ‘const’, for example by being passed as a parameter in the ‘const &’ way, can only have those of its methods that are explicitly declared ‘const’ called (because C++’s calling system is too simple work out which methods not explicitly declared ‘const’ don’t actually change anything).
    So now it sounds like he's saying using a const& is making the OBJECT that was passed to the function const, instead of just limiting the function from modifying the referenced object. So seeing as its modifying the object that was passed to make it const, that would defeat the whole purpose of making a function incapable of modifying a function by using the 'const' keyword, wouldn't it?
    operator== is usually implemented as a free function with both parameters const, so if you don't do that, at least make the method const to enforce similar behavior.
    Well, I tried that approach first, but my compiler complained that the operator could only have one parameter, so I switched it to what I have above, and now its complaining about something else.

    On the other thing you said, since I wrote the definition of the operator inside the class, wouldn't it be invalid to add the 'const' keyword after the trailing brace?

    EDIT: Nevermind on the last thing. I just put the 'const' keyword before the braces, and that appears to be valid. However, nothing changed. Still the same error.

    EDIT again: Ahh...ok. I see what you mean by 'free function'. You're obviously talking about a global function, in which case it will probably allow two parameters, instead of one.

    EDIT again: Ok, I added a global version of the operator==, which works:

    Code:
    bool operator== (const S_html_attr_value& a, const S_html_attr_value& b) {
    
        if (a.content == b.content)
           return true;
    
        return false;
    
    }
    Thanks.
    Last edited by Programmer_P; 03-03-2011 at 09:48 PM.
    I'm an alien from another world. Planet Earth is only my vacation home, and I'm not liking it.

  4. #4
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    Well, think of for example a const variable being passed to a method, but said variable is used to change the state of the object. In this way, the method does not change the value but the value changes the object.

    What you quoted applies to pointers. Fortunately there are only two ways a reference can be declared, non-const or const. A const reference is a reference that cannot be used to change the object it references, but references never amount to a copy of an object. So what you had originally typed was correct.

    operator== is declared by wikipedia as such:

    ​bool T::operator ==(const T& b) const;

    Where T is your type. If you wanted to define operator == in the class, you could, but the signature stays the same. That is, the curly brace replaces where the semicolon is.

  5. #5
    Programming Ninja In-T...
    Join Date
    May 2009
    Posts
    827
    Quote Originally Posted by whiteflags View Post

    operator== is declared by wikipedia as such:

    ​bool T:perator ==(const T& b) const;

    Where T is your type. If you wanted to define operator == in the class, you could, but the signature stays the same. That is, the curly brace replaces where the semicolon is.
    Hmm...I was about to say I tried that, but still the same compile error (because I am pretty positive it was the last time I tested it), but then I just tried that again, and this time it works?? Oh well...at least I got it to work without having to modify several hundred lines which depends on that operator.

    Thanks.

    EDIT: And I guess, for the record, technically having the operator as a member of the struct wouldn't be overloading the operator, but you know what I meant.
    Last edited by Programmer_P; 03-03-2011 at 10:02 PM.
    I'm an alien from another world. Planet Earth is only my vacation home, and I'm not liking it.

  6. #6
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    but then I just tried that again, and this time it works??
    It's only because I cast a spell after hearing your problem, obviously. Any sufficiently advanced technology is indistinguishable from magic.

  7. #7
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Let me clear up the const confusion for you.
    Basically an object being const means that its internal state must not be modified (or cannot). Of course, as a consequence of this, you can naturally not assign anything to the object.
    Furthermore, you may not call any function on this object (including operators!) that may change its internal state. Thus, you may only call functions which promise not to modify the internal state of an object (that is, they are const functions).

    Now, as to the meaning of const, it depends on where it's placed. If it's placed after a member function (but before the first curly bracket), the it indicates that the function is const. That is, it will not change its instance's internal state. This obviously doesn't work for free functions since they have no instance. Thus const cannot be applied after a free function.

    Now, const can also be applied to variables. The meaning of it depends on where the keyword is applied. The basic syntax of a variable (reference or pointer) is:
    T [modifiers] * [modifiers] name;
    T [modifiers] & [modifiers[ name;
    Everything that is left of the * or & is part of the type.
    So,
    int * foo
    means that foo name is the name and int is the type that is being pointed to.
    In case of
    const int * foo
    or
    int const * foo
    It means that the type pointed to is const int (or int const, it's the same).
    If we point to a const int, then obviously we cannot change what is pointed to (because it's const). However, we can modify the variable itself--the pointer--because it isn't const. Only what is pointed to is const.
    Now, we can also do

    int * const foo

    Because const is after the *, it means it applies to the variable and not the type. Thus, the pointer points to int. But the pointer is const. Therefore, we can change what is pointed to, but we cannot change the pointer.
    We can of course combine these two:

    const int * const foo

    This one we can neither change what is pointed to nor change the pointer itself.
    Now, let's extend this to references.
    References are special because the cannot be reassigned. Everything you try to do on a reference will simply be done on what it is a reference to.
    Thus, it would only make sense to say that there is only one type of const we can apply here, and that is the ability to change the object the reference is an alias of, or failure to do so.
    So the standard basically says that

    const int & foo
    and
    int & const foo

    are the same thing. Contrary to pointers.

    Good. That concludes it. Questions?
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  8. #8
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    An even simpler way to remember const is that any identifier with the const modifier will not appear on the left side of a statement after being declared and that is what the compiler enforces. To understand const then, you must merely understand what is being claimed constant (where explanations like Elysia's really help) and that only const methods will work on a given const object.

    It's simplified, of course, to exclude things like const data members in classes, because the only other implication there is that they're initialized in the constructor's list thing.
    Last edited by whiteflags; 03-04-2011 at 05:46 AM.

  9. #9
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    You were right up until this bit:
    Quote Originally Posted by Elysia View Post
    So the standard basically says that

    const int & foo
    and
    int & const foo

    are the same thing. Contrary to pointers.
    That part is rubbish.

    The first of those two does not allow you the assign to the object it refers to, but the second one does as it is the same as
    Code:
    int & foo
    with the const after the ampersand being redundant, since all references are unable to be reseated.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  10. #10
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    That part is rubbish.
    The relevant code isn't even valid. He was making an association to pointers as a means of explaining the nature of constant references. So, not rubbish, just a little weird.

    Soma

  11. #11
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Shame on me. I thought I knew, but I knew not.
    iMalc is correct, of course.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  12. #12
    Programming Ninja In-T...
    Join Date
    May 2009
    Posts
    827
    Quote Originally Posted by Elysia View Post
    Shame on me. I thought I knew, but I knew not.
    iMalc is correct, of course.
    Lol...you guys.
    Thanks for the lesson on 'const'. I'm now a lot clearer about that.
    I'm an alien from another world. Planet Earth is only my vacation home, and I'm not liking it.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. casting struct to struct
    By klmdb in forum C Programming
    Replies: 6
    Last Post: 08-14-2010, 02:29 PM
  2. help with structs and malloc!
    By coni in forum C Programming
    Replies: 20
    Last Post: 09-14-2009, 05:38 PM
  3. Replies: 1
    Last Post: 12-03-2008, 03:10 AM
  4. We Got _DEBUG Errors
    By Tonto in forum Windows Programming
    Replies: 5
    Last Post: 12-22-2006, 05:45 PM
  5. Replies: 10
    Last Post: 05-18-2006, 11:23 PM