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 besides Field1
        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?

Happy Green Kid Naps
  • 1,611
  • 11
  • 18
  • 1
    If it's available to you, I'm pretty sure [Boost.MultiIndex](http://www.boost.org/libs/multi_index/doc/index.html) solves your problem. – GManNickG Aug 30 '12 at 17:33
  • possible duplicate of [Assignment of data-member in read-only structure, class in STL set](http://stackoverflow.com/questions/3775414/assignment-of-data-member-in-read-only-structure-class-in-stl-set) – interjay Aug 30 '12 at 17:37
  • @GManNickG -- unfortunately, my employer will not use it. Thank you much, all the same. – Happy Green Kid Naps Aug 30 '12 at 17:38
  • Unrelated to your question, but your `operator<` means you can have `a`, `b`, `c` such that `!(a < b) && !(b < a) && !(b < c) && !(c < b)`, yet still `a < c`. –  Aug 30 '12 at 17:45
  • Appreciate the link to the other post, @interjay -- I did search before posting, and I didn't find the one that you cross-referenced. That said, my question isn't so much as to "Why" (which I understand), it is more a "How". Furthermore, the accepted answer there and here (both by James McNeillis!) are significantly different. – Happy Green Kid Naps Aug 30 '12 at 17:47
  • @hvd -- Yes, I know it is not the strictest of weak orderings. – Happy Green Kid Naps Aug 30 '12 at 17:48
  • Yes, if you ask me the same question multiple times, I am likely to give different answers. – James McNellis Aug 31 '12 at 02:59
  • @JamesMcNellis -- I am grateful for your answer -- I accepted your response as the answer. My point was this is a *different* question from the other one. Finally, I am _not_ the one who asked the previous question (i.e., I surely didn't ask the question multiple times!). – Happy Green Kid Naps Aug 31 '12 at 16:33
  • Yes, when I said "you" I meant "the internet." – James McNellis Aug 31 '12 at 20:21

2 Answers2

4
  • Declare MoreFields as mutable, or

  • const_cast the inchk.first expression to remove constness, or

  • encapsulate MoreFields within a const-qualified accessor that returns a non-const reference.

James McNellis
  • 348,265
  • 75
  • 913
  • 977
0

I would think you want to use a map instead of a set.

Tod
  • 8,192
  • 5
  • 52
  • 93