当我尝试编写一个插入函数时,会出现问题,该函数假定将数组中的所有元素上移到迭代器给定的指定位置,然后在迭代器给定的位置将新值插入到数组中
代码在插入函数中出错,并显示以下错误:
“ operator []”不匹配(操作数类型为“ std :: basic_string [1000]”和“ std :: basic_string”)
我对使用迭代器是陌生的,并且我认为不可能使用指针作为索引来访问数组元素。因此,我不确定是否还有其他方法可以执行此操作,或者我是否需要重载[]运算符才能使其以某种方式工作?
template <class T>
class Vector {
public:
typedef T* iterator;
Vector () { }
T& operator[](unsigned int i) {
return items[i];
}
// T& operator[](iterator i) {
//return items[*i];
//}
iterator begin () {
return &items[0];
}
iterator end () {
return &items[used];
}
int size () { return used; }
iterator insert (iterator position, const T& item) {
for(Vector<T>::iterator i=&items[998]; i>=position; i--)
{
items[*(i+1)]=items[*i];
}
items[*position]= item;
return position;
}
private:
T items[1000];
int used=0;
};
答案 0 :(得分:2)
此代码在创建1000个类型为T的元素的意义上是有问题的,即使在逻辑上为空。另外,如果插入次数超过1000,则将丢弃上面的元素。
关于编译问题,我尝试使用Vector<int>
编译代码,并且编译正常,但是崩溃。出于相同的原因,它与Vector<int>
一起崩溃,而没有与Vector<std::string>
一起编译。问题的类型为*i
,在std::string
的情况下为Vector<std::string>
。要么完全使用迭代器,要么使用索引,但不要混合使用。使用迭代器:
for(Vector<T>::iterator i=&items[998]; i>=position; i--)
{
*(i+1)=*i;
}
[在完成此编辑后,刚注意到Scheff的答案就知道了这一点]
由于v.insert(v.begin(), value)
在i
之前进行迭代,因此上述方法为items
调用了未定义的行为。为避免这种情况,迭代应该在items
结束之前停止:
for(Vector<T>::iterator i=&items[999]; i > position; i--)
{
*i = *(i-1);
}
此外,请注意循环后的行也应固定:
items[*position]= item; // <--- BUG: also mixing indexes and iterators
for(int i= 998; begin() + i>=position; i--)
{
items[i+1]=items[i];
}
答案 1 :(得分:1)
除了回答Michael Veksler外,我还尝试使其正常运行(因此需要更长的时间)。
因此,他提出了第一个建议的解决方案,并且
items[*position]= item;
更改为
*position = item;
以下测试将编译并运行:
#include <iostream>
int main()
{
Vector<double> vec;
vec.insert(vec.begin(), 1.0);
vec.insert(vec.begin(), 2.0);
vec.insert(vec.begin(), 3.0);
std::cout << "vec.size(): " << vec.size() << '\n';
for (int i = 0; i < vec.size(); ++i) {
std::cout << "vec[" << i << "]: " << vec[i] << '\n';
}
return 0;
}
输出:
vec.size(): 0
糟糕!
used
中也缺少insert()
的更新:
++used;
而且,现在看起来更好了:
vec.size(): 3
vec[0]: 3
vec[1]: 2
vec[2]: 1
完整的MCVE:
#include <iostream>
template <class T>
class Vector {
public:
typedef T* iterator;
Vector () { }
T& operator[](unsigned int i) {
return items[i];
}
// T& operator[](iterator i) {
//return items[*i];
//}
iterator begin () {
return &items[0];
}
iterator end () {
return &items[used];
}
int size () { return used; }
iterator insert (iterator position, const T& item) {
for(Vector<T>::iterator i=&items[998]; i>=position; i--)
{
*(i+1) = *i;
}
*position = item;
++used;
return position;
}
private:
T items[1000];
int used=0;
};
int main()
{
Vector<double> vec;
vec.insert(vec.begin(), 1.0);
vec.insert(vec.begin(), 2.0);
vec.insert(vec.begin(), 3.0);
std::cout << "vec.size(): " << vec.size() << '\n';
for (int i = 0; i < vec.size(); ++i) {
std::cout << "vec[" << i << "]: " << vec[i] << '\n';
}
return 0;
}
答案 2 :(得分:0)
因此,在这种情况下,您可以将迭代器视为指向数组元素的光荣指针,就像您在类开始时在typedef中定义的那样。
当您尝试在insert函数中访问数组中的元素时,实际上是在取消引用这些指针以产生元素本身,然后使用这些元素作为数组的索引来生成THEN,因此产生错误,即索引为类型错误。
例如,假设您有一个Vector<std::string>
。在插入函数的for循环内,您具有以下行:
items[*(i+1)]=items[*i];
因为i
是您定义的iterator
,所以i
的类型为std::string *
,因此*i
的类型为std::string
。然后,当您编写items[*i]
时,您将尝试使用std::string
作为无法执行的数组索引。
相反,您应该使用类似于以下内容的行:
*(i + 1) = *i
您的代码中也存在一些逻辑错误,但是稍后我将让您查找。
希望这会有所帮助!
答案 3 :(得分:0)
看看如何实现std::move_backward
template< class BidirIt1, class BidirIt2 >
BidirIt2 move_backward(BidirIt1 first, BidirIt1 last, BidirIt2 d_last)
{
while (first != last) {
*(--d_last) = std::move(*(--last));
}
return d_last;
}
您无需将任何元素移至end
之后,我们可以将您的insert
重写为相似的
iterator insert (iterator position, const T& item) {
for(iterator i = end(), d = end() + 1; i != position; )
{
*(--d) = std::move(*(--i));
}
*position = item;
++used;
return position;
}
请注意,如果您尝试将其插入完整的Vector