Я бы предположил, что под rank
вы на самом деле подразумеваете расстояние от корня, поскольку, если бы оно могло храниться смежно со значением, вам не пришлось бы идти на такую длину.
Я думаю, что вы могли бы сделать это "внешне", так как в этом случае ранг можно экстраполировать из числа случаев использования предиката сравнения ...
namespace detail
{
template <class Comparator>
class CounterComparator: Comparator
{
public:
CounterComparator(size_t& counter):
Comparator(), mCounter(&counter) {}
CounterComparator(Comparator comp, size_t& counter):
Comparator(comp), mCounter(&counter) {}
template <class T, class U>
bool operator()(T& lhs, U& rhs) const
{
++(*mCounter);
return this->Comparator::operator()(lhs,rhs);
}
private:
size_t* mCounter;
};
} // namespace detail
template <
class Key,
class Value,
class Cmp = std::less<Key>,
class Allocator = std::allocator< std::pair<const Key,Value> >
>
class SuperMap
{
typedef detail::CounterComparator<Cmp> Comparator;
public:
SuperMap(): mCounter(0), mData(Comparator(mCounter)) {}
Value& operator[](const Key& key) { return mData[key]; }
size_t rank(const Key& key) const
{
mCounter = 0; mData.find(key); return mCounter;
}
private:
typedef std::map<Key,Value, Comparator, Allocator> data_type;
mutable size_t mCounter;
data_type mData;
}; // class SuperMap
int main(int argc, char* argv[])
{
SuperMap<int,int> superMap;
superMap[1] = 42;
std::cout << superMap.rank(1) << std::endl;
}
// outputs
// 2
Подсчитывает количество тестов, но, поскольку std::map
прекращает тестирование, как только получает правильный ключ ... все должно быть в порядке :) Хотя, вероятно, есть некоторое смещение, чтобы вывести (1 или 2), чтобы ранг вместо.
Если вы дадите лучшее определение rank
, я могу работать немного больше, но я не хочу тратить слишком много времени в неправильном направлении.