for 循环中的向量迭代器、返回语句、警告、c++
Posted
技术标签:
【中文标题】for 循环中的向量迭代器、返回语句、警告、c++【英文标题】:Vector iterators in for loops, return statements, warning, c++ 【发布时间】:2010-06-10 03:49:12 【问题描述】:我有三个关于 C++ 家庭作业的问题。目标是创建一个简单的回文方法。这是我的模板:
#ifndef PALINDROME_H
#define PALINDROME_H
#include <vector>
#include <iostream>
#include <cmath>
template <class T>
static bool palindrome(const std::vector<T> &input)
std::vector<T>::const_iterator it = input.begin();
std::vector<T>::const_reverse_iterator rit = input.rbegin();
for (int i = 0; i < input.size()/2; i++, it++, rit++)
if (!(*it == *rit))
return false;
return true;
template <class T>
static void showVector(const std::vector<T> &input)
for (std::vector<T>::const_iterator it = input.begin(); it != input.end(); it++)
std::cout << *it << " ";
#endif
关于上面的代码,你可以在 for 循环的第一部分声明多个迭代器吗?我尝试在 palindrome() 方法中同时定义“it”和“rit”,但我不断收到关于在 rit 之前需要“,”的错误。但是当我在 for 循环之外剪切和粘贴时,编译器没有错误。 (我使用的是 VS 2008)。
第二个问题,我几乎只是在这个问题上放屁。但是我在回文()方法中返回语句的方式可以吗?在我的脑海中,我认为它的工作方式类似于,一旦 *it 和 *rit 不相等,则函数返回 false,此时方法退出。否则,如果它一直通过 for 循环,那么它在最后返回 true。我完全不知道 return 语句在 if 块中是如何工作的,我试着在我的书中查找一个很好的例子,但我找不到。
最后,我收到以下警告:
\palindrome.h(14) : warning C4018: '<' : signed/unsigned mismatch
现在是因为我运行我的 for 循环直到 (i
【问题讨论】:
你不需要声明你的函数模板static
.
【参考方案1】:
迭代器是家庭作业的要求吗?这个任务可以简化为对std::equal
的调用:
template <class T>
bool palindrome(const std::vector<T> &input)
return equal(input.begin(), input.begin()+input.size()/2, input.rbegin());
【讨论】:
Cheater ;-)(和+1...非常好的解决方案)【参考方案2】:你可以在 for 循环的第一部分声明多个迭代器吗?
是的,但它们必须是同一类型,因此您不能同时声明 const_iterator
和 const_reverse_iterator
。
我在回文()方法中返回语句的方式好吗?
是的,不过为什么不直接比较*it != *rit
?
palindrome.h(14) : warning C4018: '<' : signed/unsigned mismatch
i
已签名; std::vector::size()
返回一个无符号值。如果i
未签名,您将不会收到此警告。
不过,作为一个建议:使用两个前向迭代器可能更简单。将一个初始化为.begin()
,另一个初始化为.end() - 1
。然后你可以增加第一个并减少第二个,你的循环测试就变成了it1 < it2
。类似于以下(完全未经测试)的 for 循环:
for (iterator it1(v.begin()), it2(v.end() - 1); it1 < it2; ++it1, --it2)
这样您就不再需要单独的i
计数器和比较;一切都是用迭代器完成的。
【讨论】:
您最后的建议仅适用于随机访问迭代器,因为只有那些支持减法。 @Tomek:是的。 OP 使用的是std::vector
,它利用了随机访问迭代器。您还可以使用std::prev()
(C++0x 加法,但实现起来很简单)来获取最后一个元素的迭代器;然后将需求减少为双向迭代器。
您不能将双向迭代器与除相等之外的任何东西进行比较(==
和!=
可以,但<
不行),因此要求仍然是随机访问迭代器。它可以重写为仅使用相等比较,但这需要在循环体内移动增量/减量(至少一个)并检查以避免两个迭代器在具有偶数个元素的容器中交叉。
@David:你是对的;当我发表评论时,我没有注意。感谢您的指正。也就是说,我仍然认为这将是比使用 size()
的任何解决方案更好的解决方案,因为 size()
可能具有线性复杂性(例如,对于 std::list
的某些实现)。
我同意,代码少了一个要求(不使用'size'),更小更干净。【参考方案3】:
当迭代器属于同一类型时,for
循环适用于我,我还没有想出其他方法 - 除了像你所做的那样在外面初始化它们:
typedef vector<char>::const_iterator IT;
for (IT it(vchars.begin()), end(vchars.end()); it != end; ++it)
cout << *it << endl;
关于 return 语句,您的推理是正确的,但是您从这 2 个迭代器开始时并不相同,一个从前面开始,另一个从末尾开始。所以在第一次迭代中它们不相等,你返回 false - 我相信。
最后,警告指出size()
返回无符号类型(大小不能为负)但您与有符号值i
进行比较,这在大多数情况下不是一个真正的问题 - 但整洁,您可以将您的 i
声明为未签名。
这将解决这个问题:
for (unsigned int i = 0; i < input.size()/2; ...)
【讨论】:
以上是关于for 循环中的向量迭代器、返回语句、警告、c++的主要内容,如果未能解决你的问题,请参考以下文章