Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ STL set: Compare object with extrinsic state

Tags:

c++

compare

set

stl

This definitions are inside of OuterClass:

struct Compare
{
    bool operator ()(const T&, const T&);
};
typedef set<T, Compare> MySet;

My problem is that the compare function operator () depends on the state of OuterClass. (MySet instances are used during an algorithm for an optimization and they have to sort differently at different stages.)

Is there any way/workaround to access nonstatic members of OuterClass from within the compare function operator ()?

like image 909
schoettl Avatar asked Apr 28 '13 09:04

schoettl


People also ask

How do you create a custom comparator for a set?

auto cmp = [](int a, int b) { return ... }; std::set<int, decltype(cmp)> s; We use lambda function as comparator. As usual, comparator should return boolean value, indicating whether the element passed as first argument is considered to go before the second in the specific strict weak ordering it defines.

How do I compare sets in CPP?

The '==' is an operator in C++ STL performs equality comparison operation between two unordered sets and unordered_set::operator== is the corresponding operator function for the same. Parameters: This operator function takes reference of two unordered sets uset1 and uset2 as parameters which are to be compared.

Can we compare two sets in CPP?

C++ std operator== C++ std operator== is a non-member overloaded function of set in C++. This function is used to check whether the two sets are equal or not.

How do you define a comparator in C++?

Comparator Classes are used to compare the objects of user-defined classes. In order to develop a generic function use template, and in order to make the function more generic use containers, so that comparisons between data can be made.


1 Answers

Is there any way/workaround to access nonstatic members of OuterClass from within the compare function operator ()?

There is. Just write a user-defined constructor for Compare that accepts and stores a reference to OuterClass, this way:

struct Compare
{
    Compare(OuterClass& o) : oc(o) { }
    bool operator ()(const T&, const T&)
    {
        // Uses oc somehow...
    }
private:
    OuterClass& oc;
};

Then, when you create your set, you can do something like:

int main()
{
    typedef std::set<T, Compare> MySet;

    OuterClass oc; // <== Construct an object of type Outerclass somehow...

    MySet ms(Compare(oc)); // <== Construct your comparator and pass it
                           //     in input to the constructor of std::set
}

Beware though: the ordering criterion should remain stable. Elements must always compare the same for the same set. Per paragraph 23.2.4/3 of the C++11 Standard:

The phrase “equivalence of keys” means the equivalence relation imposed by the comparison and not the operator== on keys. That is, two keys k1 and k2 are considered to be equivalent if for the comparison object comp, comp(k1, k2) == false && comp(k2, k1) == false. For any two keys k1 and k2 in the same container, calling comp(k1, k2) shall always return the same value.

like image 197
Andy Prowl Avatar answered Sep 29 '22 05:09

Andy Prowl