2011-10-19 69 views
6

有這樣的代碼:裹STL向量和改變行爲

#include <iostream> 
#include <vector> 

template <class T> 
class A{ 
public: 
    class iterator : public std::vector<T>::iterator{ 
    public: 
     T& operator*(){ 
      ?? 
     } 
    }; 

    iterator begin(){ 
     return v.begin(); // error 
    } 

    iterator end(){ 
     return v.end(); // error 
    } 

    void add(const T& elem){ 
     v.push_back(elem); 
    } 

private: 
    std::vector<T> v; 
}; 

int main() { 
    A<int> a; 
    a.add(2); 
    a.add(4); 
    for(A<int>::iterator it = a.begin(); it != a.end(); ++it){ 
     std::cout << *it << std::endl; 
    } 
    return 0; 
} 

這是std::vector用我自己的附加功能的包裝。我想用std::vector的迭代器,但我只想要更改的迭代器operator*行爲:

T& operator*(){ 
    // do some additional function 
    // normal behavior, return value of some element in vector 
      ?? 
} 

如何使用std::vector及其僅爲operator*修改迭代器?我還想爲迭代器打包begin()end()等函數,如何正確包裝它們?

編輯:

使用技巧從這個話題的答案,我設法解決我在下面的方式問題:

#include <iostream> 
#include <vector> 

template <class T> 
class A { 
public: 

    class iterator : public std::vector<T>::iterator { 
    public: 

     iterator(typename std::vector<T>::iterator c) : std::vector<T>::iterator(c) { 
     } 

     T& operator*() { 
      std::cout << "Im overloaded operator*\n"; 
      return std::vector<T>::iterator::operator *(); 
     } 
    }; 

    iterator begin() { 
     return iterator(v.begin()); 
    } 

    iterator end() { 
     return iterator(v.end()); 
    } 

    void add(const T& elem) { 
     v.push_back(elem); 
    } 

private: 
    std::vector<T> v; 
}; 

int main() { 
    A<int> a; 
    a.add(2); 
    a.add(4); 

    for (A<int>::iterator it = a.begin(); it != a.end() ; ++it) { 
     std::cout << *it << std::endl; 
    } 
    return 0; 
} 

也許會有人幫助。

+0

是的。我誤解了代碼。不知道這是怎麼發生的。 –

回答

3

包裝stdlib迭代器最好用迭代器適配器完成。這個任務遠不是微不足道的,並且有一個Boost.Iterator庫來簡化任務。也許其中一個提供的迭代器已經解決了你的問題。

如果你打算寫這個你自己(我真的不建議這樣做),你應該實現自己的迭代器,並讓它成爲constructible從vector::iterator,然後重載所有經營者必須滿足要求你的新迭代器模型的概念。也從std::iterator繼承,以獲得性狀的工作。不要忘了有一個const變體。 This book有一章致力於開發自己的迭代器。也可以獲取標準的副本(C++ 03或C++ 11,這裏並不重要)。你將需要它。

+1

如果他想透明地使用它(他的問題建議),他還需要實現'std :: vector'的包裝。 –

+0

@BjörnPollex該課程看起來像他只需要一個適配器。他的類看起來並不是「Sequence」的完整模型,並且暴露'begin()'和'end()'應該只需要迭代器。 – pmr

1

不幸的是,唯一的方法是編寫一個完整的包裝函數std::vector及其迭代器類型。這是很多工作。

-1

我想這裏的答案很可能是你不應該改變了運算符*的行爲爲一個迭代器。操作符重載只能在非常直觀的情況下才能完成,任何閱讀使用操作符的代碼的人都會自動知道發生了什麼。一個例子是如果你有一個矩陣類和重載的operator +。當有人看到你將兩個矩陣對象加在一起時,他們可以很容易地知道發生了什麼。

但是,當解引用一個迭代器時,沒有什麼直觀的感覺會對你的類產生什麼樣的附加副作用。

+1

哦,改變'operator *'的行爲可能是非常有用的。認爲'轉換迭代器'。 – pmr

1

其中一個不會從std::vector<T>::iterator繼承,因爲它不需要是類。在某些實現中,這只是T*的typedef,並且不能從指針繼承。一個人也不應該從標準容器繼承,因爲他們缺乏虛擬析構函數;可能會繼承privateprotected的方式,並通過typedefusing使所有符號和功能可見。最後,你將不得不重寫整個向量及其迭代器,它們將調用轉發給基礎實現。