1

I am trying to make my question simple here. I have one structure with int array as member variable.

struct elem
{
    elem (int a, int b, int c) {id[0]=a; id[1]=b; id[2]=c;}
    int id[3];
};

I want to put elem pointers into std::set and I want to use find() to search specific object from that set later, so I want to provide custom comparator to this std::set.

struct compare
{
    bool operator() (elem *one, elem *two )
    {
            // logic 
    }
};

int main(int argc, char* argv[])
{
    std::set< elem *, compare> elemSet;
    std::set< elem *, compare>::iterator itr;

    elem ob1(2,5,9), ob2(5,9,7), ob3(4,3,7);

    elemSet.insert(&ob1);
    elemSet.insert(&ob2);
    elemSet.insert(&ob3);

    elem temp(4,3,7);
    itr = elemSet.find(&temp);

    if(itr != elemSet.end())
    {
        cout << endl << (*itr)->id[0] << " " << (*itr)->id[1] << " " << (*itr)->id[2]; 
    }

    return 0;
}

Can you please help me with logic for comparator? Is there any generic logic for array of any size?

Shrik
  • 41
  • 3

1 Answers1

2

Since std::set (and std::map and their multi variants) want strict-weak ordering, you need to provide that ordering through the comparator. Strict-weak ordering demands that

(x < x) == false
(x < y) == !(y < x)
((x < y) && (y < z)) == (x < z)

Which can be complicated to implement for classes with many members (an array is just a collection of members if you so want).

In this question of mine I asked if it was sensible to implement strict-weak ordering through tuple and tie, which make it ridiculously easy:

struct compare
{
    bool operator() (elem const* one, elem const* two )
    {   // take 'tie' either from Boost or recent stdlibs
        return tie(one->id[0], one->id[1], one->id[2]) <
               tie(two->id[0], two->id[1], two->id[2]);
    }
};

Also notice that I take the arguments as pointers-to-const.

Community
  • 1
  • 1
Xeo
  • 129,499
  • 52
  • 291
  • 397