我的代码在作为参数传入 .begin() 时不起作用,但在我将 .begin() 转换为迭代器后工作



我正在尝试创建自己的向量类。 目前,我正在努力为我的矢量类添加一个名为 Vec 的擦除函数。当我将 variable.begin(( 传递到 erase 函数参数中时,我的代码会抱怨,但在我手动将 variable.begin(( 转换为迭代器然后将其传入后正常运行。

有人可以向我解释为什么会发生这种奇怪的情况吗?

int main(){
Vec<string> words;
words.push_back("h");
words.push_back("a");
words.push_back("p");
Vec<string>::iterator iter=words.begin();
Vec<string>::iterator iter1=words.end();
words.erase(words.begin(),words.end());//this does not work
words.erase(iter,iter1);//this works
}
//Function erase in the Vec class i created

template <class T> class Vec {
typedef T* iterator;//
typedef const T* const_iterator;
iterator data; // first element in the Vec
iterator avail; // (one past) the last element in the Vec
iterator limit; // (one past) the allocated memory
void erase(iterator&i, iterator&j){
iterator new_limit=limit;
iterator new_avail=avail;
size_t a=j-i+1;
size_t n=limit-data;
n=n-a;
iterator new_data=alloc.allocate(n);
iterator mid=std::uninitialized_copy(data,data+1,new_data);
size_t b=size();
if(j!=avail){
new_limit, new_avail=std::uninitialized_copy(j+1,avail,mid);
data=new_data;
avail=new_avail;
limit=new_limit;
}
else{
data=new_data;
limit=avail=data+n;
}
}
}

void erase(iterator&i, iterator&j)的定义相当可疑。

iterator&意味着您必须有一个现有变量才能绑定到(非常量(引用。迭代器在设计上是"指针等效项",通常按值传递。你不会写void erase(string*&i, string*&j).

最简单的解决方案是将erase更改为void erase(iterator i, iterator j)

此外,您还没有将任何东西"转换"为迭代器。您已将迭代器分配给迭代器变量。编译器抱怨所涉及的表达式的值类别。

要了解为什么它不起作用,请举这个例子:

void test(int& r)
{
}
int a = 42;
test(a);

a是一个左值,可以绑定到非常量引用。

另一方面,从以下func()返回的值是临时值,只能绑定到常量引用、值或右值引用。

int func() { return 42; }
test(func()); // error

要使其正常工作,您必须将func()的返回值分配给左值,或者更改test()函数以接受常量引用。

a = func();
test(a);

void test(int const & r)
{
}
test(func());

现在,用erase()代替test(),用begin()/end()代替func(),你应该知道为什么它不起作用。

您的erase()函数看起来不正确。它应该接受常量迭代器,而是返回一个迭代器(如果擦除后向量为空,则返回最后一个删除的元素或end(。

iterator erase(const_iterator first, const_iterator last);

最新更新