map :: tipe yang dipetakan const_iterator bukan const
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
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
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.