0
template<class T>
class State {
    T state;
    double cost = 0;
    State<T> *cameFrom = nullptr;

I have this template class, and i want to create a std::set<State<T>>

the < operator of the class returns this.cost < other.cost

the == operator of the class returns this.state == other.state

lets say i want to check if a State<T> x is in a set

how can i make the set to return an iter !- end()(calling set.find(x)) iff the set contains a State<T> with the same state(x.state) as x?

AD1234
  • 19
  • 1
  • 5
  • 1
    Possible duplicate of [Find elements of std::set by custom comparison with value of different type](https://stackoverflow.com/questions/48176182/find-elements-of-stdset-by-custom-comparison-with-value-of-different-type) – Daniel Langr Jan 09 '19 at 11:41
  • 3
    I question the idea of a type where `a < b` and `a == b` can be true at the same time. – Max Langhof Jan 09 '19 at 11:58
  • 1
    Possible duplicate of [Using custom std::set comparator](https://stackoverflow.com/questions/2620862/using-custom-stdset-comparator) – Max Langhof Jan 09 '19 at 12:04

1 Answers1

0

std::set does not care about operator==, it uses an equivalence relation defined to have the same results as

bool equiv(T a, T b)
{
    if (a < b) return false;
    if (b < a) return false;
    return true;
}

If you have State<T> values with differing state but equal cost, only one of them can go in your std::set.

You might have success with a boost::multi_index_container, where you can look things up by either cost or state

namespace bmi = boost::multi_index;
using state_set = boost::multi_index_container<State<T>, 
    bmi::indexed_by<
        bmi::ordered_unique<bmi::member<State<T>, double, &State<T>::cost>>,
        bmi::ordered_non_unique<bmi::member<State<T>, T, &State<T>::state>>
    >
>;

state_set set = ...;
auto & states_view = set.nth_index<1>();
if (auto it = states_view.find(x); it != states_view.end())
    ...
Caleth
  • 52,200
  • 2
  • 44
  • 75