map :: const_iterator ชนิดที่แมปไม่ใช่ const

Sep 02 2020

ฉันกำลังพยายามเขียนอะแดปเตอร์ตัววนซ้ำสำหรับคลาสที่สร้างไว้ด้านบนของแผนที่ ฉันมีปัญหาเมื่อพยายามรับประเภทที่แมปจากประเภทตัววนซ้ำ โดยทั่วไปฉันต้องการรับ:

  • แผนที่ <Key, Val> :: iterator -> Val
  • แผนที่ <Key, Val> :: const_iterator -> Val const

นี่คือ 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");

ฉันจะบรรลุสิ่งนั้นได้อย่างไร (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 คู่ที่เป็นเพียงไม่ไม่เพียง dereferencing จะกลับอ้างอิง แต่จะไม่เปลี่ยนที่ทั้งคู่ไป หากคุณต้องการที่ตรวจสอบว่า iterator ที่คล้ายกันเป็นหรือไม่เช่นมีและถ้าเป็นเช่นนั้นให้ใช้ของมันเช่นกับstd::pair<const Key, T>second_typeTconst Tconst T&Tmap::const_iteratorconst pair&second_typeconstvalue_typeconststd::is_constconstsecond_typestd::add_const