如何使用const InputIterators为泛型容器编写函数
How to use const InputIterators to write a function for generic containers?
我试图理解如何编写一个(独立)函数,该函数接受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
的要求,用begin
和end
分别替换cbegin
和cend
,代码工作得很好。有人能指出我遗漏了什么吗?
你需要通过value:
传递你的迭代器template <class InputIterator>
void print(InputIterator first, InputIterator last)
{
// as before
}
print
不会修改任何内容的契约是隐含的,因为您从不分配给*first
。
确实需要修改迭代器本身(要实际进行任何迭代),也就是说,您不能通过const&
获取它们(否则,首先必须再次复制它们)-但是修改迭代器与修改底层内容不同。
这种混淆似乎是由于混合了迭代器和迭代器所指向的数据。
- 迭代器可以被变量化,同时保持指向的只读。
让我们将这些概念映射到原始指针:
int buffer[ARRAY_SIZE];
const int *ptr2c = &(buffer[0]);
与
int * const cptr = &(buffer[0]);
考虑使用这两个指针中的任意一个遍历'buffer'的元素。使用'ptr2c',应该能够在数组上循环;不能通过这个变量修改数组元素。
另一方面,'cptr',一个指向int的const指针,允许您修改数组中的指向元素。但是,cptr本身不能被修改为指向任何其他位置。
映射回你的例子,'const InputIterator'使迭代器本身不可修改,这不是你想要的。这很粗糙,但是,你可以把迭代器想象成指针。当然,这两个概念很快就产生了分歧。
相关文章:
- 如果有一个模板构造函数只有一个泛型参数,为什么我必须有一个复制构造函数
- 链表的泛型函数remove()与成员函数remove)
- 将参数传递给泛型 lambda 时复制构造函数不正确
- 泛型枚举和其他类型的重载模板函数
- 可变参数泛型 lambda 和函数重载
- 以特征类型作为参数的泛型函数回调
- 传递非泛型函数的最有效方法是什么?
- 泛型模板函数始终返回整数值
- 泛型函数反向打印任何矢量,编译器出错
- C++泛型包装类,它为某些函数添加了额外的处理
- 是否可以在C++中创建泛型函数指针?
- 必须具有泛型接口的函数,但必须根据传递的子类(不知道它们是什么!)以不同的行为 - C++
- 是否可以使用泛型枚举类型作为函数的参数?
- 将泛型函数及其参数传递给元函数
- 如何在带有约束 (C++) 的函数中使用泛型类型
- 获取模板函数/泛型 lambda 的唯一返回类型
- 这是为浮点数/双精度函数泛型的正确方法吗?
- 使字段函数泛型
- 将函数泛型地传递给c++模板
- 我如何使这个函数泛型,以便它接受任何容器