例如在此代码段的开头和结尾,似乎被用作指针。但是在函数声明中,* beg中,* end既未提供,也未被c ++编译器接受。为什么我们像使用指针一样使用它,却不像函数的指针参数那样声明它?
#include <vector>
#include <algorithm>
#include <iostream>
#include <iterator>
using namespace std;
template<class In, class X> void myreplace (In beg, In end, const X& x, const X& y)
{
while (beg != end)
{
if (*beg == x) *beg = y;
beg++;
}
}
int main()
{
vector<int> veca = { 1, 3, 4, 4, 1, 4, 4 };
myreplace(veca.begin(), veca.end(), 4, 2);
copy(veca.begin(), veca.end(), ostream_iterator<int>(cout, ","));
}
答案 0 :(得分:1)
Iterators通常不仅是指针,而且是指针的抽象。
根据他们的general requirements:
它们的语义是C ++中大多数指针语义的概括。这样可以确保每个使用迭代器的函数模板都可以正常工作 常规指针。
因此,您也可以改为这样做:
myreplace(&veca[0], &veca[6], 4, 2);
&veca[0]
和&veca[6]
是指向向量veca
的第一个和最后一个元素的指针。
之所以可行,是因为 [] operator返回对指定位置元素的引用。
答案 1 :(得分:0)
可以通过重载一元operator*
函数为任何使用定义的类型定义解引用运算符。
veca.begin()
返回的类型就是这种类型。可以使用*
运算符取消引用该类型的对象。
由标准库中大多数容器的begin()
成员函数返回的迭代器支持这种操作。因此,您可以使用:
std::vector<int> a = {10, 20, 30};
std::vector<int>::iterator iter = a.begin();
int item = *iter;
和
std::set<int> a = {10, 20, 30};
std::set<int>::iterator iter = a.begin();
int item = *iter;
和
std::map<int, double> a = {{10, 2.5}, {20, 5.8}};
std::map<int, double>::iterator iter = a.begin();
std::pair<int, double> item = *iter;
答案 2 :(得分:0)
没有什么可以阻止您将指针传递到myreplace
。例如在通话中
int Carray[7] = { 1, 3, 4, 4, 1, 4, 4 };
myreplace(Carray, Carray + 7, 4, 2);
推论模板参数In
为int *
,推论X
为int
。就像你写的一样
void myreplace (int * beg, int * end, const int & x, const int & y)
{
while (beg != end)
{
if (*beg == x) *beg = y;
beg++;
}
}
它也接受行为充分类似于指针的非指针(即模型InputIterator)
答案 3 :(得分:-2)
您的意思是否正确,如下所示:
template<class In, class X> void myreplace (In* beg, In* end, const X& x, const X& y)
{
while (*beg != *end)
{
if (**beg == x) **beg = y;
*beg++;
}
}
我认为首先您应该了解C ++的基本模板知识,实际上,在STL中,迭代器定义为指针,但这并不意味着指针类型是迭代器唯一的指针
typedef T* iterator;