請原諒我,如果這是一個微不足道的問題,我只是在學習C++,並試圖圍繞某些概念來包裝我的頭。特別是當涉及迭代器時,我完全失去了。C++迭代器在向量中的某些元素
說我有一個自定義類表示一些數據結構,其中一個成員是一個整數向量。我想爲該類編寫一個雙向迭代器,該向量只輸出偶數。有一種簡單而有益的方法嗎?我不喜歡使用STL以外的庫。
請原諒我,如果這是一個微不足道的問題,我只是在學習C++,並試圖圍繞某些概念來包裝我的頭。特別是當涉及迭代器時,我完全失去了。C++迭代器在向量中的某些元素
說我有一個自定義類表示一些數據結構,其中一個成員是一個整數向量。我想爲該類編寫一個雙向迭代器,該向量只輸出偶數。有一種簡單而有益的方法嗎?我不喜歡使用STL以外的庫。
#include <vector>
#include <iostream>
class X {
public:
class EvenIterator {
public:
EvenIterator(std::vector<int>::iterator it, std::vector<int>::iterator end) : it(it), end(end) {
while (true) {
if (isEven(*it)) {
break;
} else if (it == end) {
break;
}
it++;
}
}
bool operator != (const EvenIterator& evenIt) {
return evenIt.it != this->it;
}
int operator *() {
return *it;
}
EvenIterator operator ++() {
while (true) {
it++;
if (isEven(*it)) {
return EvenIterator(it, end);
} else if (it == end) {
return EvenIterator(it, end);
}
}
}
private:
std::vector<int>::iterator it;
std::vector<int>::iterator end;
};
static bool isEven(int number) {
return number % 2 == 0;
}
void add(int number) {
v.push_back(number);
}
EvenIterator evenBegin() {
return EvenIterator(v.begin(), v.end());
}
EvenIterator evenEnd() {
return EvenIterator(v.end(), v.end());
}
private:
std::vector<int> v;
};
int main() {
X x;
x.add(1);
x.add(2);
x.add(3);
x.add(2);
x.add(2);
x.add(31);
x.add(56);
x.add(101);
for (X::EvenIterator it = x.evenBegin(); it != x.evenEnd(); ++it){
std::cout << *it << std::endl; // only prints the even numbers
}
}
太棒了,這看起來非常像我期望我的代碼看起來像是如果我知道如何去做的;-)它應該是數字%2 == 0,但是: - ) – user32849 2014-09-10 19:46:15
你真的想檢查結束條件,然後去引用迭代器... – jrok 2014-09-10 19:48:58
該版本獲取第一個元素,即使它是奇數。應該是'iterator evenBegin(){ \t \t std :: vector
不確定讓自己的迭代器很容易。但可能最好的是使用條件for_each
函數。
std::for_each
對每個元素進行操作。創建一個for_each_if
對某些特定元素進行操作非常簡單。例如,下面的程序只打印矢量中的偶數(4,6和8)。
#include <iostream>
#include <vector>
using namespace std;
struct is_even {
typedef bool return_type;
bool operator() (const int& value) {return (value%2)==0; }
};
struct doprint {
bool operator() (const int& value) { std::cout << value << std::endl; }
};
template <class InputIterator, class Predicate, class Function>
void for_each_if(InputIterator first, InputIterator last, Function f, Predicate pred)
{
while (first != last)
{
if (pred (*first))
f(*first++);
else
first ++;
}
}
int main()
{
std::vector<int> v;
v.push_back(4);
v.push_back(5);
v.push_back(6);
v.push_back(8);
for_each_if(v.begin(), v.end(), doprint(), is_even());
return 0;
}
你的要求去,從vector::iterator
獲得很可能是最簡單的:
class my_iterator : private std::vector<int>::iterator {
typedef std::vector<int>::iterator base;
base m_base_end; // Stores the real end iterator of the internal vector.
// We need it so that the even/odd checking code
// doesn't run off the end of the vector
// (initialize it in a constructor, omitted here for
// brevity).
public:
using base::operator*;
using base::operator->;
// etc. for other members...
// except for increment:
my_iterator& operator++()
{
do {
base::operator++();
} while(static_cast<base&>(*this) != m_base_end
&& base::operator*() % 2);
return *this;
}
my_iterator operator++(int)
{
my_iterator temp;
operator++();
return temp;
}
// TODO: decrement and other arithmetic operators
};
它仍然是相當多的樣板,你還需要爲const_iterator
做同樣的(我'd可能會讓上面的類變得更容易)。
考慮提高這一點 - 它有filter_iterator
只是爲了這個目的。如果那不適合你,也有iterator_adaptor
。
此解決方案是非常危險,可能有太多其他代碼出現。例如,這個循環很可能會崩潰,因爲'erase'也應該被覆蓋:'my_iterator iter = v.begin(); while(iter!= v.end()){if(cond)++ iter; else iter = v.erase(); }'。而且,是'vector :: operator ++''virtual'?因爲非虛函數不應該被覆蓋...... – jpo38 2014-09-13 15:54:23
爲什麼你不告訴我們你到目前爲止? – lordjeb 2014-09-10 18:48:54
我知道你不想使用其他庫,但是如果其他人閱讀這個問題並不介意使用它們,Boost已經[filter iterator](http://www.boost.org/doc/libs/1_56_0) /libs/iterator/doc/filter_iterator.html)。 – cdhowie 2014-09-10 18:50:19
您是否想要在偶數索引處輸出偶數或數字? – dlf 2014-09-10 19:23:54