0
votes

How?I found a lot of examples, but the example with template of the parameter could not be found. I somehow did not work comparator.

std::map<K, CacheEntry<T>*, Comparator<K, CacheEntry<T>>> timeMap_;

template<typename T1, typename T2>
        struct Comparator
        {
            typedef std::pair<T1, T2> type;
            bool operator()(const type& l, const type& r) const
            {
                auto nowTime = std::chrono::system_clock::now();
                auto timeL = nowTime - l.second->creationTime();
                auto timeR = nowTime - r.second->creationTime();
                return (std::chrono::duration_cast<std::chrono::microseconds>(timeL).count() > std::chrono::duration_cast<std::chrono::microseconds>(timeR).count());
            }
        };

Error:

Error 1 error C2664: 'bool diadoc::cache::Comparator *>::operator ()(const std::pair &,const std::pair &) const' : cannot convert argument 1 from 'const std::wstring' to 'const std::pair &' c:\program files (x86)\microsoft visual studio 12.0\vc\include\xutility 521 1 DiadocClient

I try use:

template<typename T1, class T2>

But it's too not working. Sort by the second parameter map.

2
What's K in your example? Anyway, the comparator object passed to std::map must accept two objects of type K as arguments. Can't you just switch the template arguments to map? - Angew is no longer proud of SO
@Angew K - is the key, but I do not want to sort by key. I need to sort the field creationTime_ class CacheEntry. That is, I want to sort on the second field. - Tipok
That doesn't make sense. std::map sorts by key, and uses the fact that its contents is sorted to provide logarithmic-time uniqueness checks and access. Can you specify your requirements clearly: What are your uniqueness criteria, sorting criteria, access/modification time complexity criteria? It might turn out you need a more complex container such as boost::multi_index. - Angew is no longer proud of SO
There is a unique key that we find an object that stores the time and value. The bottom line is that when I want to delete the oldest member, I appeal to him map.begin (). This container does not suit me? - Tipok
Please try to formulate the requirements a bit more clearly and add them to the question; it will improve it greatly (actually make it answerable on its own, that is). - Angew is no longer proud of SO

2 Answers

1
votes

From your comments, it seems you need a container which will:

  • Store objects which contain K and CacheEntry<T>
  • Not allow two objects with the same value of K
  • Sort the objects based on CacheEntry<T>

There is no standard container which supports this directly. You could use boost::multi_index_container, like this:

typedef std::pair<K, CacheEntry<T>*> DataItem;


MyTimeType getTime(const DataItem &item)
{
  return getTimeSomehowFrom(item);
}


typedef multi_index_container<
  DataItem,
  indexed_by<
    ordered_non_unique<global_fun<DataItem, MyTimeType, &getTime>>,
    hashed_unique<member<DataItem, K, &DataItem::first>>
  >
> MyContainer;

(The code assumes all relevant #includes and using namespace directives for brevity).

The above code is not in copy&paste&use shape, but it should be a pointer to get you started. You can read up on the multi-index container and build on the above idea to suit your needs (such as adding tags for indices).

The order of indices (ordered, then unique) matters - for convenienec, the container itself inherits the interface of the first index. In the above case, this would allow you to treat it like a collection of DataItems ordered by the results of getTime(), while not allowing duplicate values of K.


As a side note, notice that you don't need to drag now() into your comparator. If (now - t1) < (now - t2), then simply t2 > t1.

1
votes

Not sure what you're trying to do, but std::map compares keys only(that is the type K in you sample code).

You defined a comparator that compares a pair, which is not what std::map needed, hence the error.

If your map may contain multiple entries with same key, you should use multimap instead.