map :: const_iterator il tipo mappato non è const
Sto cercando di scrivere un adattatore iteratore per una classe costruita sopra una mappa. Ho problemi durante il tentativo di ottenere il tipo mappato dal tipo iteratore. Fondamentalmente mi piacerebbe ottenere:
- map <Key, Val> :: iterator -> Val
- map <Key, Val> :: const_iterator -> Val const
Ecco una riproduzione minima.
#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");
Come posso ottenerlo (C ++ 14)?
Risposte
Per quasi tutti gli scopi pratici, i tipi che potresti voler dedurre sono legati a qualche espressione, nel qual caso decltypeè sempre la risposta
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
Il value_typedi un std::mapè std::pair<const Key, T>. Il valore second_typedi quella coppia è solo T, non const T, non const T&, solo T. Dereferenziare a map::const_iteratorrestituirà un const pair&riferimento, ma ciò non cambierà quella coppia second_typein const. Se lo desideri, rileva se l'iteratore value_typeè consto meno, come con std::is_const, e in tal caso applicalo constal suo second_type, come con std::add_const.