2013-02-18 56 views
2

無論是否設計良好,我的main()方法都會根據正在使用的數據結構(由輸入參數確定)來聲明一個變量,該變量需要符合BidirectionalIterator定義(特別是list<>::iteratorvector::iterator)的任何迭代器。由於我無法模擬main()方法,因此如何完成此操作?可能定義一個C++變量來接受任何BidirectionalIterator?

,而不是例如:

int main(int argc, const char* argv[]) { 
    vector<Person>::iterator iterator0; 
    list<Person>::iterator iterator1); 
    multimap<string, Person>::iterator iterator2; 
} 

由於所有有迭代器滿足BidirectionalIterator的要求,我想做的事:

int main(int argc, const char* argv[]) { 
    bidirectionaliterator iterator0; 
} 

然後,我沒有檢查什麼不斷程序使用if語句來存儲迭代器並使用我想要的迭代器的數據結構。

+2

你能更具體地說明你想做什麼嗎?目前,這聽起來像是你想將迭代器傳遞給'main()',這是沒有意義的。 – us2012 2013-02-18 04:41:10

+5

請顯示實際的代碼(而不僅僅是描述)。 – 2013-02-18 04:41:15

+1

請顯示實際的代碼(*以及*給出說明)。 – Johnsyweb 2013-02-18 04:44:31

回答

1

這聽起來像你想的typedef:

typedef std::vector<Person> person_container; 
typedef person_container::iterator mybidirectionaliterator; 

然後隨時要改變底層的容器,你所要做的就是改變std::vector<Person>到別的東西。雖然,你仍然不能在這裏分配任何迭代器,但你必須使用兼容的迭代器。但是,您是否熟悉C++ 11中的auto關鍵字?很多時候你再也不用寫出迭代器了,即auto myiter = some_container.begin();就足夠了。

此外,爲了獲得更好的答案,它有助於展示如何使用迭代器而不是僅僅聲明它。

1

我認爲你要找的是類型擦除。你可以把它看作是一個接口的逆向。您可以將界面想象爲坐在課堂底部,確定需要提供哪些方法。在頂部附着一種類型的被擦除物體,並「提取」某些方法,引入鴨子打字。有an upcoming Boost Type Erasure library這將使這是一個易於使用的概念。

下面是它如何工作的純C++ 11(它可以很容易地製作在工作前11 C++爲好,但我想 使用unique_ptr):

#include<iostream> 
#include<vector> 
#include<list> 
#include<memory> 
using namespace std; 

class Person{}; 


template <class T> 
class TypeErasedBidirectionalIterator { 
public: 
    virtual void operator++()=0; 
    virtual void operator--()=0; 
    virtual T& operator*()=0; 
}; 

template <class T, class Iterator> 
class BidirectionalIteratorAdaptor: public TypeErasedBidirectionalIterator<T> { 
    Iterator it; 
public: 
    BidirectionalIteratorAdaptor(Iterator it): it(it){} 
    void operator++(){it++;} 
    void operator--(){it--;} 
    T& operator*(){*it;} 
}; 

template <class Iterator> 
unique_ptr<BidirectionalIteratorAdaptor<typename Iterator::value_type,Iterator> > makeIterator(Iterator it) { 
    typedef typename Iterator::value_type T; 
    return unique_ptr<BidirectionalIteratorAdaptor<T,Iterator> >(new BidirectionalIteratorAdaptor<T,Iterator>(it)); 
} 

typedef TypeErasedBidirectionalIterator<Person> PersonIterator; 
typedef unique_ptr<PersonIterator> PersonIteratorPtr; 


int main() { 
    vector<Person> vec; 
    list<Person> lst; 
    lst.push_back(Person()); 
    PersonIteratorPtr it = makeIterator(vec.begin()); 
    it = makeIterator(lst.begin()); 
    ++*it; 
    --*it; 
    **it; 
} 

注意,通過包裝PersonIteratorPtr在另一個類中直接暴露了方法 ,您可以擺脫類似指針的行爲,但我並不想讓概念驗證更復雜。

相關問題