Reputation: 669
I am trying to define a class with a map of K
-> pair
of V
and iterator of a list
of K
. This is to implement LRU cache. I got this working with decltype
:
template <typename K, typename V> class LRUCache {
std::list<K> q;
typedef decltype(q.begin()) Iterator;
typedef std::pair<V, Iterator> Node;
int max_size;
std::map<const K, Node> m;
}
However, I am not satisfied with using decltype
and it all seems brittle when I try to use it. What would be the canonical way of doing this?
Upvotes: 1
Views: 494
Reputation: 669
To add to the answers of others - the std::list<K>::iterator
is a dependent type and C++ requires us to use typename
in front of it.
The reason for this is that the compiler doesn't know whether ::iterator
is a type, so it needs a hint with typename
.
Another way of dealing with the original issue is to use using
template, similar to the way some of <type_traits>
are defined in C++14. We can define:
template <typename T> using ListIterator = typename std::list<T>::iterator;
Now, we can simply use ListIterator<K>
in the LRUCache code:
template <typename K, typename V> class LRUCache {
using Node = std::pair<V, ListIterator<K>>;
std::list<K> q;
std::map<const K, Node> m;
int max_size;
}
Upvotes: 0
Reputation: 5209
I quite do not like old fashioned way of using typedef
, since it seems to use reverse syntax for declaring stuff. You are also using int i = 5
and not int 5 i
. (Not only) for this, new usage of using
was introduced.
using Iterator = decltype(a.begin());
If you do not like decltype
, you can use std::list<K>::iterator
, but because K
is template parameter, std::list<K>
is dependent name and needs to be prefixed with typename
.
using Iterator = typename std::list<K>::iterator;
Or with old fashioned typedef
typedef typename std::list<K>::iterator Iterator;
Upvotes: 1
Reputation: 5557
The type of the iterator is
std::list<K>::iterator
If you want to use it, you have to use a typename
in front of it, or alias it first with a
using iterator = typename std::list<K>::iterator;
However, using decltype
there seems to be a perfectly valid use of it, if you can be sure everyone calling this code has c++11 or later.
Upvotes: 0