Accessing member via set's NON-const iterator that doesn't affect invariants

Discussion in 'C++' started by Anand Hariharan, Aug 30, 2012.

  1. Let's say I have code like so:

    #include <set>
    #include <math.h>

    typedef int OtherTypes;

    struct MyType
    {
    double Field1;
    OtherTypes MoreFields;

    MyType(double blah) :
    Field1(blah)
    {
    }

    bool operator < (const MyType &That) const
    {
    // Does not use any other member
    return ( fabs(Field1 - That.Field1) > 1e-6 &&
    Field1 < That.Field1 );
    }
    };

    int main()
    {
    std::set<MyType> foo;
    std::pair< std::set<MyType>::iterator,
    bool > inchk = foo.insert(MyType(1.0));

    OtherTypes SomeVal = 1;
    if ( inchk.second )
    inchk.first->MoreFields = SomeVal; // error
    }


    How do I reassure the compiler that writing MoreFields will not affect
    any invariants or will not do anything to invalidate the order of
    elements in the set?

    If the only recourse is to use another container such as vector, how
    do I insert a new value in the sorted position while checking if one
    exists already?
    Anand Hariharan, Aug 30, 2012
    #1
    1. Advertising

  2. Re: Accessing member via set's NON-const iterator that doesn't affectinvariants

    On 8/30/2012 1:14 PM, Anand Hariharan wrote:
    > Let's say I have code like so:
    >
    > #include <set>
    > #include <math.h>
    >
    > typedef int OtherTypes;
    >
    > struct MyType
    > {
    > double Field1;
    > OtherTypes MoreFields;
    >
    > MyType(double blah) :
    > Field1(blah)
    > {
    > }
    >
    > bool operator < (const MyType &That) const
    > {
    > // Does not use any other member
    > return ( fabs(Field1 - That.Field1) > 1e-6 &&
    > Field1 < That.Field1 );
    > }
    > };
    >
    > int main()
    > {
    > std::set<MyType> foo;
    > std::pair< std::set<MyType>::iterator,
    > bool > inchk = foo.insert(MyType(1.0));
    >
    > OtherTypes SomeVal = 1;
    > if ( inchk.second )
    > inchk.first->MoreFields = SomeVal; // error
    > }
    >
    >
    > How do I reassure the compiler that writing MoreFields will not affect
    > any invariants or will not do anything to invalidate the order of
    > elements in the set?


    Perhaps you should declare 'MoreFields' "mutable"?

    > If the only recourse is to use another container such as vector, how
    > do I insert a new value in the sorted position while checking if one
    > exists already?


    If your vector is sorted, use 'lower_bound' (or is it 'upper_bound'?) to
    find the place where the sorting would place your element, then compare
    what you want to insert to what's already there (the next element or the
    previous, can't divine now) thus /checking/ if one exists.

    V
    --
    I do not respond to top-posted replies, please don't ask
    Victor Bazarov, Aug 30, 2012
    #2
    1. Advertising

  3. On Aug 30, 12:25 pm, Victor Bazarov <> wrote:
    > On 8/30/2012 1:14 PM, Anand Hariharan wrote:
    >
    >
    >
    >
    >
    >
    >
    >
    >
    > > Let's say I have code like so:

    >
    > > #include <set>
    > > #include <math.h>

    >
    > > typedef int OtherTypes;

    >
    > > struct MyType
    > > {
    > >      double Field1;
    > >      OtherTypes MoreFields;

    >
    > >      MyType(double blah) :
    > >          Field1(blah)
    > >      {
    > >      }

    >
    > >      bool operator < (const MyType &That) const
    > >      {
    > >          // Does not use any other member
    > >          return ( fabs(Field1 - That.Field1) > 1e-6 &&
    > >                   Field1 < That.Field1 );
    > >      }
    > > };

    >
    > > int main()
    > > {
    > >      std::set<MyType> foo;
    > >      std::pair< std::set<MyType>::iterator,
    > >                 bool > inchk = foo.insert(MyType(1.0));

    >
    > >      OtherTypes SomeVal = 1;
    > >      if ( inchk.second )
    > >          inchk.first->MoreFields = SomeVal; // error
    > > }

    >
    > > How do I reassure the compiler that writing MoreFields will not affect
    > > any invariants or will not do anything to invalidate the order of
    > > elements in the set?

    >
    > Perhaps you should declare 'MoreFields' "mutable"?
    >


    Thank you, Victor! I'd forgotten all about that keyword despite that
    I'd argued a case for that keyword with a colleague many years ago.


    > > If the only recourse is to use another container such as vector, how
    > > do I insert a new value in the sorted position while checking if one
    > > exists already?

    >
    > If your vector is sorted, use 'lower_bound' (or is it 'upper_bound'?) to
    > find the place where the sorting would place your element, then compare
    > what you want to insert to what's already there (the next element or the
    > previous, can't divine now) thus /checking/ if one exists.
    >


    That is more tedious than the alternative of simply declaring other
    fields as mutable, IMHO.

    thank you again,
    - Anand
    Anand Hariharan, Aug 30, 2012
    #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. cheeser
    Replies:
    17
    Views:
    723
    cpp_weenie
    Oct 18, 2003
  2. Michael Klatt

    A non-const std::set iterator

    Michael Klatt, Apr 5, 2004, in forum: C++
    Replies:
    13
    Views:
    5,875
    Michael Klatt
    Apr 7, 2004
  3. David Scarlett
    Replies:
    3
    Views:
    831
    mlimber
    Feb 7, 2006
  4. Javier
    Replies:
    2
    Views:
    558
    James Kanze
    Sep 4, 2007
  5. fungus
    Replies:
    13
    Views:
    884
    fungus
    Oct 31, 2008
Loading...

Share This Page