map :: tipe yang dipetakan const_iterator bukan const

Sep 02 2020

Saya mencoba menulis adaptor iterator untuk kelas yang dibangun di atas peta. Saya mengalami masalah saat mencoba mendapatkan tipe yang dipetakan dari tipe iterator. Pada dasarnya saya ingin mendapatkan:

  • peta <Key, Val> :: iterator -> Val
  • peta <Key, Val> :: const_iterator -> Val const

Ini repro minimal.

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

Bagaimana saya bisa mencapai itu (C ++ 14)?

Jawaban

2 PasserBy Sep 02 2020 at 08:18

Untuk hampir semua tujuan praktis, tipe yang ingin Anda simpulkan terkait dengan beberapa ekspresi, dalam hal decltypeini selalu jawabannya

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

The value_typedari std::mapadalah std::pair<const Key, T>. The second_typepasangan yang hanya T, tidak const T, tidak const T&, hanya T. Dereferensi a map::const_iteratorakan mengembalikan const pair&referensi, tetapi itu tidak akan mengubah pasangan itu second_typemenjadi const. Jika Anda menginginkannya, deteksi apakah iteratornya value_typeada constatau tidak, seperti with std::is_const, dan jika demikian maka terapkan constke iteratornya second_type, seperti with std::add_const.