map :: const_iterator eşlenen tür sabit değil

Sep 02 2020

Bir haritanın üstüne kurulmuş bir sınıf için bir yineleyici bağdaştırıcısı yazmaya çalışıyorum. Yineleyici türünden eşlenen türü almaya çalışırken sorun yaşıyorum. Temel olarak şunu almak istiyorum:

  • map <Anahtar, Değer> :: yineleyici -> Değer
  • map <Anahtar, Değer> :: const_iterator -> Değer sabit

İşte minimal bir 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");

Bunu nasıl başarabilirim (C ++ 14)?

Yanıtlar

2 PasserBy Sep 02 2020 at 08:18

Neredeyse tüm pratik amaçlar için, çıkarmak isteyebileceğiniz türler bir ifadeye bağlıdır, bu durumda decltypeher zaman cevaptır.

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_typeA std::mapolduğunu std::pair<const Key, T>. Bu second_typeçiftin sadece Tdeğil const T, değil const T&, sadece T. Bir dereferencing map::const_iteratorbir döner const pair&referans, ama bu, söz konusu ikili var değişmeyecek second_typeiçin const. Bunu isterseniz, yineleyici olsun algılamak value_typeolduğu constböyle olduğu gibi, ya da değil std::is_const, ve bu yüzden daha sonra uygularsanız constonun için second_typeolduğu gibi, bu tür std::add_const.