Отображаемый тип map :: const_iterator не является const

Sep 02 2020

Я пытаюсь написать адаптер итератора для класса, построенного поверх карты. У меня возникла проблема при попытке получить сопоставленный тип из типа итератора. В основном я бы хотел получить:

  • map <Key, Val> :: iterator -> Val
  • map <Ключ, Val> :: const_iterator -> Val const

Вот минимальное воспроизведение.

#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");

Как я могу этого добиться (C ++ 14)?

Ответы

2 PasserBy Sep 02 2020 at 08:18

Практически для всех практических целей типы, которые вы, возможно, захотите вывести, привязаны к некоторому выражению, и в этом случае decltypeвсегда будет ответ.

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
2 RemyLebeau Sep 02 2020 at 07:54

value_typeИз std::mapесть std::pair<const Key, T>. То, second_typeчто в этой паре, просто T, нет const T, не const T&справедливо T. Разыменование map::const_iteratorвернет const pair&ссылку, но не изменит эту пару second_typeна const. Если вы хотите , что обнаружить , является ли итератор value_typeэто constили нет, например, с std::is_const, и если да , то обратиться constк его second_type, например, с std::add_const.