有人可以向我解释一下C ++中const iterator
引用和non-const iterator
引用之间的区别吗?
为什么我无法在non-const iterator
函数中使用print
引用?
以下代码无法编译。
#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;
}
错误信息对我来说有点神秘。
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) {
我设法更改代码(基于另一个代码示例)以使其工作。
#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;
}
我得到了一个结果。
1 2 3 4 5 6 7 8 9 10
我认为差异是const iterator
引用和non-const iterator
引用的声明。但我不明白为什么。我检查了C++ Reference,我试图回顾我的课程,但我没有成功获得理解。
答案 0 :(得分:6)
这与const和非const迭代器无关。在这一行:
print(d2.rbegin(), d2.rend()) << endl;
rbegin()
和rend()
返回reverse_iterator
类型的临时对象。另一方面,print()
采用左值引用:
template<typename T> ostream & print(T & start, T & end);
你不能对一个临时值进行左值引用,因此代码无法编译。错误恰恰说明了 - 您正在尝试使用临时函数初始化非const引用:
hello.cpp:21:33:错误:从'std :: deque :: reverse_iterator {aka std ::'类型的右值开始,无效初始化类型'std :: reverse_iterator&gt;&amp;'的非const引用reverse_iterator&gt;}'
你可以使用临时初始化 const 引用,这就是你的修复工作的原因。但实际上,你根本不需要参考。只需编写print()
以按值获取其迭代器:
template<typename T>
ostream & print(T start, T end) {
for (; start != end; ++start) {
cout << *start << " ";
}
return cout;
}
整个标准库算法套件都是这样做的。像标准库那样做。