我正在尝试创建自己的向量类。 目前,我正在努力为我的矢量类添加一个名为 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);