理解C++中对const迭代器的const引用和非const引用.为什么我不能在print函数中使用非const引用到迭代器?

Ely*_*Ely 0 c++ iterator const

有人可以向我解释C++中const iterator引用和non-const iterator引用之间的区别吗?为什么我不能non-const iteratorprint函数中使用引用?


以下代码无法编译.

#include <deque>
#include <iostream>

using namespace std;

template<typename T> ostream & print(T & start, T & end) {
    for (; start != end; ++start) {
        cout << *start << " ";
    }
    return cout;
}

int main() {
    int tab[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    deque<int> d1(tab, tab + 10);
    deque<int> d2;
    deque<int>::iterator it;
    for (it = d1.begin(); it != d1.end(); ++it) {
        d2.push_back(d1[d1.end() - it - 1]); //LINE I
    }
    print(d2.rbegin(), d2.rend()) << endl; //LINE II
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

错误信息对我来说有点神秘.

hello.cpp:21:33: error: invalid initialization of non-const reference of type ‘std::reverse_iterator<std::_Deque_iterator<int, int&, int*> >&’ from an rvalue of type ‘std::deque<int>::reverse_iterator {aka std::reverse_iterator<std::_Deque_iterator<int, int&, int*> >}’
     print(d2.rbegin(), d2.rend()) << endl; //LINE II
                                 ^
hello.cpp:6:32: error: in passing argument 1 of ‘std::ostream& print(T&, T&) [with T = std::reverse_iterator<std::_Deque_iterator<int, int&, int*> >; std::ostream = std::basic_ostream<char>]’
 template<typename T> ostream & print(T & start, T & end) {
Run Code Online (Sandbox Code Playgroud)

我设法更改代码(基于另一个代码示例)以使其工作.

#include <deque>
#include <iostream>

using namespace std;

template<typename T> ostream & print(const T & start, const T & end) {
    T tmp = start;
    for (; tmp != end; ++tmp) {
        cout << *tmp << " ";
    }
    return cout;
}

int main() {
    int tab[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    deque<int> d1(tab, tab + 10);
    deque<int> d2;
    deque<int>::iterator it;
    for (it = d1.begin(); it != d1.end(); ++it) {
        d2.push_back(d1[d1.end() - it - 1]); //LINE I
    }
    print(d2.rbegin(), d2.rend()) << endl; //LINE II
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我得到了一个结果.

1 2 3 4 5 6 7 8 9 10 
Run Code Online (Sandbox Code Playgroud)

我认为差异是const iterator参考和non-const iterator参考的声明.但我不明白为什么.我检查了C++ Reference,我试着回顾一下我的课程,但是我没有成功获得理解.

Bar*_*rry 6

这与const和非const迭代器无关.在这一行:

print(d2.rbegin(), d2.rend()) << endl;
Run Code Online (Sandbox Code Playgroud)

rbegin()rend()返回类型的临时工reverse_iterator.print()另一方面,采用左值引用:

template<typename T> ostream & print(T & start, T & end);
Run Code Online (Sandbox Code Playgroud)

你不能把一个左值引用带到临时,所以代码无法编译.错误确切地说 - 您正在尝试使用临时初始化非const引用:

hello.cpp:21:33:错误:从'std :: deque :: reverse_iterator {aka std :: reverse_iterator>}'类型的右值开始,无效初始化'std :: reverse_iterator>&'类型的非const引用

可以使用临时初始化const引用,这就是您的修复工作的原因.但实际上,你根本不需要参考.只需编写你print()的值来获取它的迭代器:

template<typename T>
ostream & print(T start, T end) {
    for (; start != end; ++start) {
        cout << *start << " ";
    }
    return cout;
}
Run Code Online (Sandbox Code Playgroud)

整个标准库算法套件就是这样做的.像标准库那样做.