I'm trying to write an iterator adaptor for a class built on top of a map. I'm having issue when trying to get the mapped type from the iterator type. Basically I'd like to get:
Here is a minimal repro.
#include <map>
#include <type_traits>
template <typename BaseIteratorT>
using ValueType = typename BaseIteratorT::value_type::second_type;
// Passes
static_assert(
std::is_same<ValueType<std::map<double, int>::iterator>, int>::value,
"bad type for mutable iterator");
// Fails
static_assert(
std::is_same<ValueType<std::map<double, int>::const_iterator>, const int>::value,
"bad type for const iterator");
How can I achieve that (C++14)?
For almost all practical purposes, types you might want to deduce is tied to some expression, in which case decltype
is always the answer
template<typename T>
using mapped_type = std::remove_reference_t<decltype((std::declval<T>()->second))>;
using m = std::map<char, int>;
using i = mapped_type<m::iterator> // int
using ci = mapped_type<m::const_iterator> // const int
The value_type
of a std::map
is std::pair<const Key, T>
. The second_type
of that pair is just T
, not const T
, not const T&
, just T
. Dereferencing a map::const_iterator
will return a const pair&
reference, but that will not change that pair's second_type
to const
. If you want that, detect whether the iterator's value_type
is const
or not, such as with std::is_const
, and if so then apply const
to its second_type
, such as with std::add_const
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With