我试图理解如何编写一个(独立的)函数,该函数接受const InputIterators并在迭代容器中的每个元素时执行一些简单的操作。为简单起见,我考虑使用简单的打印函数,它会打印[first..last)
之间范围内的所有元素,但不允许该函数修改容器中的元素。这是我到目前为止所得到的:
#include<iostream>
#include<vector>
#include<list>
using namespace std;
template<class InputIterator>
void print(const InputIterator& first, const InputIterator& last)
{
while (first != last) {
cout << *first << " ";
++first;
}
cout << endl;
}
int main()
{
vector<int> v;
v.push_back(1);
v.push_back(3);
v.push_back(5);
v.push_back(7);
list<float> l;
l.push_back(11.1);
l.push_back(33.3);
l.push_back(55.7);
l.push_back(77.7);
print(v.cbegin(), v.cend());
print(l.cbegin(), l.cend());
}
当我尝试编译代码时(使用带有c ++ 11标志的gcc4.7),我收到以下错误:
iterator.cpp: In instantiation of 'void print(const InputIterator&, const InputIterator&) [with InputIterator = __gnu_cxx::__normal_iterator<const int*, std::vector<int> >]':
iterator.cpp:32:29: required from here
iterator.cpp:12:5: error: passing 'const __gnu_cxx::__normal_iterator<const int*, std::vector<int> >' as 'this' argument of '__gnu_cxx::__normal_iterator<_Iterator, _Container>& __gnu_cxx::__normal_iterator<_Iterator, _Container>::operator++() [with _Iterator = const int*; _Container = std::vector<int>; __gnu_cxx::__normal_iterator<_Iterator, _Container> = __gnu_cxx::__normal_iterator<const int*, std::vector<int> >]' discards qualifiers [-fpermissive]
iterator.cpp: In instantiation of 'void print(const InputIterator&, const InputIterator&) [with InputIterator = std::_List_const_iterator<float>]':
iterator.cpp:33:29: required from here
iterator.cpp:12:5: error: passing 'const std::_List_const_iterator<float>' as 'this' argument of 'std::_List_const_iterator<_Tp>::_Self& std::_List_const_iterator<_Tp>::operator++() [with _Tp = float; std::_List_const_iterator<_Tp>::_Self = std::_List_const_iterator<float>]' discards qualifiers [-fpermissive]
我注意到,如果删除const
要求,将cbegin
和cend
替换为begin
和end
,则代码可以正常运行分别。有人可以指出我在这里失踪了吗?
答案 0 :(得分:3)
您需要按值传递迭代器:
template <class InputIterator>
void print(InputIterator first, InputIterator last)
{
// as before
}
print
不会修改任何内容的合同是隐含的,因为您从未分配给*first
。
你做需要自己修改迭代器(实际进行任何迭代),你不能通过const&
来接受它们(否则,首先要做的是&#39) ; d必须再次复制它们 - 但修改迭代器与修改底层内容不同。
答案 1 :(得分:0)
混淆似乎源于混合迭代器和迭代器指向的数据。
让我们将这些概念映射到原始指针:
int buffer[ARRAY_SIZE];
const int *ptr2c = &(buffer[0]);
Vs以上。
int * const cptr = &(buffer[0]);
考虑使用这些指针中的任何一个循环遍历&#39; buffer&#39;的元素。使用&#39; ptr2c&#39;,应该能够遍历数组;不能通过此变量修改数组元素。
另一方面,&#39; cptr&#39;,一个const-pointer-to-int,允许您修改数组中的指向元素。但是,cptr本身不能被修改为指向任何其他位置。
映射回您的示例,&#39; const InputIterator&#39;使迭代器本身不可修改,这不是你想要的。这很粗糙,但是,您可以根据指针来显示迭代器。当然,这些概念后来很快就出现了分歧。