当前位置: 首页 > 知识库问答 >
问题:

对于输入和输出迭代器,`operator*`返回值的常量有哪些规则?

拓拔谭三
2023-03-14

我正在定义自定义容器的迭代器。迭代器实现InputIterator和OutputIterator概念。

什么类型应该用于迭代器::引用常量迭代器::引用?对于迭代器常量迭代器常量迭代器,操作符*应该返回哪些类型?

迭代器的情况下,是否应该有两个运算符*的定义?如下所示(T是包含的值类型):

template<typename T>
class iterator {
public:
using reference = T&;
...
T& operator*() { return ...reference to the underlying storage... }
const T& operator*() const { return ...const reference to the underlying storage... }
...
};

或者只有一个:

T& operator*() const { return ...reference to the underlying storage... }

换句话说,常量迭代器是否允许对底层容器的可变访问?

对于const_iterator的情况,我猜想下面是正确的吗?

template<typename T>
class const_iterator {
public:
using reference = const T&;
...
const T& operator*() const { return ...reference to the underlying storage... }
...
};

或者const_iterator::reference的定义应该是T吗

除了一个完整的答案,我希望能参考一个权威的来源,在那里我可以在未来查找类似的信息。


共有2个答案

昝晗昱
2023-03-14

迭代器::引用和常量迭代器::引用应该使用什么类型?

如果您想知道应该为迭代器特性指定什么类型(iterator::referenceiterator::pointer,等等),您可以尝试模仿std::vector的功能,以下程序在编译时会告诉您需要知道的一切(实时演示)

#include <vector>

template <typename...>
struct WhichType;

int main() {
    auto vec = std::vector<int>{};
    WhichType<typename decltype(vec.begin())::difference_type>{};
    WhichType<typename decltype(vec.begin())::value_type>{};
    WhichType<typename decltype(vec.begin())::pointer>{};
    WhichType<typename decltype(vec.begin())::reference>{};
    WhichType<typename decltype(vec.begin())::iterator_category>{};

    WhichType<typename decltype(vec.cbegin())::difference_type>{};
    WhichType<typename decltype(vec.cbegin())::value_type>{};
    WhichType<typename decltype(vec.cbegin())::pointer>{};
    WhichType<typename decltype(vec.cbegin())::reference>{};
    WhichType<typename decltype(vec.cbegin())::iterator_category>{};
}

对于迭代器、常量迭代器和常量迭代器,运算符*应该返回哪些类型?

运算符*对于常规的非const_迭代器应该返回对基础类型的可变引用,如果容器的语义学允许,就不会有歧义。例如std::map迭代器返回对key类型的const引用,因为在std::map中不应该修改key(参见https://stackoverflow.com/a/32510343/5501675)

const迭代器表达了与T*constconst std::unique\u ptr相同的含义

由于迭代器是const,因此不能调用运算符()(或预增量运算符)将迭代器前进到下一个位置。无法执行此操作,因为该方法不是常量。正因为如此,大多数代码从不使用自身为常量的迭代器。最好使用对基础类型的常量引用。

const_迭代器的定义是为了解决迭代器向基础类型返回const引用的问题。因此,它们返回对底层类型的常量引用。现场演示

至于它应该有什么typedef,编译时的第一个代码示例应该告诉您

常量迭代器是否允许对底层容器进行可变访问?

是的,如果容器有。例如std::vector

或者const_iterator::reference的定义应该是T

请参阅上面的实时演示,当您编译代码时,您将看到它是一个常量

裘丰
2023-03-14

换句话说,常量迭代器是否允许对底层容器的可变访问?

是的。const迭代器不是const的迭代器;什么是const本身,而不是它指向的对象。(它类似于const指针;即T*constconstd::unique_ptr

或者const_iterator::reference的定义应该是T

它应该返回const T

 类似资料:
  • 本文向大家介绍C ++中的输入迭代器,包括了C ++中的输入迭代器的使用技巧和注意事项,需要的朋友参考一下 在本教程中,我们将讨论一个程序,以了解C ++中的输入迭代器。 输入迭代器是STL中五个最弱,最简单的迭代器之一。它们主要用于串行输入操作,在该操作中,每个值都被读取为一个值,然后迭代器移至下一个值。 示例 输出结果

  • 本文向大家介绍C++ 使用输出迭代器,包括了C++ 使用输出迭代器的使用技巧和注意事项,需要的朋友参考一下 示例 通过将输出迭代器传递给函数,可以返回相同类型的多个值。这对于一般功能(例如标准库的算法)尤其常见。 例: 用法示例:            

  • 将这些视为对象: 查看java文档,对于LinkedList类,LinkedList类中没有迭代器方法的实现,但是,实现是在AbstractSequentialList类中。 listIterator()方法在AbstractList类中实现,AbstractSequentialList的父类,总结一下,如果我没弄错的话,它返回一个不使用节点概念的迭代器对象。 但是方法是在LinkedList类中

  • 给定这9个单词,在页面上显示与其所选数字对应的单词1.mercury2.venus3.earth4.mars5.jupiter6.saturn7.uranus8.neptune9.pluto 我不确定我在这里错过了什么,我做了很多尝试,一个错误,似乎没有什么工作。 我尝试使用NumEntry作为所有if语句的比较,但它不起作用。当我使var NumEntry=true;只有水星会显示。当我做var

  • 本文向大家介绍C ++编程中的输出迭代器,包括了C ++编程中的输出迭代器的使用技巧和注意事项,需要的朋友参考一下 在本教程中,我们将讨论一个程序,以了解C ++中的输出迭代器。 输出迭代器是主要的五个迭代器的一部分。它们与输入迭代器的功能相反,它们可以被分配值,但不能被访问以获取值。 示例 输出结果

  • 输出 用print加上字符串,就可以向屏幕上输出指定的文字。比如输出'hello, world',用代码实现如下: >>> print 'hello, world' print语句也可以跟上多个字符串,用逗号“,”隔开,就可以连成一串输出: >>> print 'The quick brown fox', 'jumps over', 'the lazy dog' The quick brown