Question

I have a container like this:

// Sort functor
struct SortByTime :
  std::binary_function<const TimeSortableData &, const TimeSortableData &, bool>
{
    bool operator()(const TimeSortableData & a, const TimeSortableData & b) const
    {
        return a.GetTime() < b.GetTime();
    }
};

// Container that sorts by time
typedef std::multiset<TimeSortableData, SortByTime> TimeSortedData;

Now if I want to get the last data object before time t, I could create a dummy object and call upper_bound():

TimeSortableData dummy(t);
TimeSortedData::const_iterator it = mySortedData.upper_bound(dummy);
--it;
// result = *it;

This gives me logarithmic search complexity.
Aside from looking clumsy, this approach is problematic if such a dummy object is very hard to create (not wrt. run-time performance but coding effort).

I've looked at std::multiset::key_comp but I don't see how I could use it..
Both std::multiset::find() and std::binary_search() want me to give them the container's key_type, i.e. TimeSortableData objects...

How can I search eficiently without having to create a dummy object?

Update from comments:
There is also find_if(): It would spare me the effort of creating a dummy object but at the price of O(n) complexity.

Was it helpful?

Solution

I suppose that if your keys are so expensive to construct that you worry about creating a temporary dummy key, you can always change your code to use an std::multimap instead. Let the key be something cheap to construct, such as an integer or time_t or whatever GetTime() returns, and then the data_type could be the larger data.

typedef std::multimap<time_t, TimeSortableData> TimeSortedData;
TimeSortedData mySortedData;

...

time_t dummy = [whatever];
TimeSortedData::const_iterator it = mySortedData.upper_bound(dummy);
if (it != mySortedData.begin()) --it; // Check that iterator isn't at beginning
result = it->second;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top