【问题标题】:const_iterator and constness of const_iterator::value_typeconst_iterator 和 const_iterator::value_type 的 constness
【发布时间】:2012-09-30 22:16:13
【问题描述】:

为什么在 STL 中

std::iterator_traits<const T*>::value_type

类型相同
std::iterator_traits<T*>::value_type

为什么要这样设计?第一个不应该是const T,第二个不应该是T吗?您应该如何采用迭代器的底层 const 正确类型?我知道您可以编写自己的模板类和专业化并从中获取它

    std::iterator_traits<const T*>::pointer

但是不应该有一个成员 typedef 来保存它吗?

【问题讨论】:

  • 您能解释一下“采用底层的 const 正确类型”吗? “拿”是什么意思?
  • 我的意思是,如果我想从迭代器或从 iterator_traits 作为成员 typedef 获取“const T”,当迭代器指向 const 类型时。
  • 我明白了。不过,我不确定会有什么好的用例。可以举个例子吗?
  • 假设您想要获取类型 iterator_traits::value_type::some_member_const_dependent_type 并且如果它是一个 const 迭代器,您希望它是 const。
  • T 的 constness 不会影响 T::type,因此将 iterator_traits::value_type 设为 const 对此无济于事。

标签: c++ iterator const-iterator iterator-traits


【解决方案1】:

常量对于值类型无关紧要,因为值意味着一个副本。但是,std::iterator_traits&lt;const T*&gt;::referenceconst T&amp;

例如,你可以写这个函数:

template <class Iterator>
typename std::iterator_traits<Iterator>::value_type getValue(Iterator i)
{
  return *i;
}

无论 Iterator 是 const T * 还是 T *,它都能正常工作。

【讨论】:

  • 如果value_typeconst T,该函数也可以正常工作:)
  • @JonathanWakely:是的。我喜欢你的例子。
  • @JonathanWakely:但这有意义吗? const 返回类型存在相关限制。
  • @MatthieuM。它可能对类类型有意义,但不知道 value_type 是什么你不能说。关键是它有效。
【解决方案2】:

它允许我这样做:

std::iterator_traits<I>::value_type val = *iter;
val += 5;
doSomething(val);

但如果 value_type 是 const 则更难,因为我需要使用 remove_const

如果我不想获得可修改的值,那么 value_type 是否为 const 都没有关系:

const std::iterator_traits<I>::value_type cval = *iter;
std::iterator_traits<I>::reference        ref  = *iter;

这两种方法都适用于 const 迭代器和非常量迭代器,无论 value_type 是否为 const 都适用,但第一个示例仅适用于 const 迭代器,前提是它们的 value_type 是非常量的。

您应该如何采用底层的 const 正确类型的迭代器?

迭代器不一定有它自己的底层类型,迭代器通常指的是某个范围或某个集合,而那个集合就是具有底层类型的集合。例如std::list&lt;int&gt;::const_iteratorvalue_typestd::list&lt;int&gt;::value_type,这是int 而不是const int

你不一定想知道底层类型是什么,你更有可能想知道*iter的结果是什么,这就是iterator_traits&lt;I&gt;::reference告诉你的。

【讨论】:

  • +1:这是一个很好的例子,说明为什么它不是 const 是好的。
  • 我猜是这样,因为它更有用,正如您在示例中指出的那样。
  • 引用:“一个迭代器不一定有它自己的底层类型,一个迭代器通常是指某个范围或某个集合,而那个集合是有一个底层类型的。” “const T*”可以指代“const T”类型集合的迭代器或“T”类型集合的const迭代器。它接缝没有办法区分“std::iterator_traits”是什么意思,所以“更好”假设你的意思是它是一个 const 迭代器。
  • 最好不要假设任何一个,并且有一个适用于两者的一致模型。
  • 我的意思是,std::iterator_traits 原样假定“const T*”是“T”类型集合的 const 迭代器。
猜你喜欢
  • 2021-02-20
  • 1970-01-01
  • 2012-11-29
  • 2011-11-13
  • 2014-03-24
  • 1970-01-01
  • 2013-12-10
  • 1970-01-01
  • 2012-05-10
相关资源
最近更新 更多