【问题标题】:map::const_iterator mapped type is not constmap::const_iterator 映射类型不是 const
【发布时间】:2020-12-21 02:08:22
【问题描述】:

我正在尝试为构建在地图之上的类编写迭代器适配器。尝试从迭代器类型获取映射类型时遇到问题。基本上我想得到:

  • map::iterator --> Val
  • map::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)?

【问题讨论】:

  • 这段代码中pair&lt;A,B&gt;::second_type 始终为B 的问题,成员typedefs 不会根据constness 变形
  • 为什么要const val?这没有道理。如果您想将val&amp; 引用到const val&amp;,那么它会有意义但没有价值。
  • value_type 是类型而不是引用类型。因此,常数无关紧要。 stackoverflow.com/a/12821204

标签: c++


【解决方案1】:

出于几乎所有实际目的,您可能想要推断的类型与某个表达式相关联,在这种情况下,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】:

    std::mapvalue_typestd::pair&lt;const Key, T&gt;。那对的second_type 只是T,不是const T,不是const T&amp;,只是T。取消引用 map::const_iterator 将返回 const pair&amp; 引用,但这不会将该对的 second_type 更改为 const。如果需要,请检测迭代器的value_type 是否为const,例如std::is_const,如果是,则将const 应用于其second_type,例如std::add_const

    【讨论】:

    • 你是对的。基于此,我提供了一个基于迭代器和 const_iterator 类型的部分模板特化的实现。还有另一个基于 std::conditional 和 std::is_const 的解决方案。 @PasserBy 解决方案更简单。
    猜你喜欢
    • 2021-04-21
    • 1970-01-01
    • 2015-05-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多