无论是否通过良好的设计,我的main()
方法都声明了一个变量,它需要期望任何满足BidirectionalIterator
定义的迭代器(特别是list<>::iterator
或vector::iterator
)在使用什么数据结构(由输入参数确定)。由于我无法模板main()
方法,如何实现这一目标?
例如,而不是:
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-statements来存储迭代器和使用我想要的迭代器的数据结构类型。
答案 0 :(得分: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 :(得分:1)
我认为你要找的是 Type Erasure 。您可以将其视为接口的反转。您可以将界面想象为坐在类的底部,确定它需要提供哪些方法。一种类型的擦除对象在顶部附加,并“提取”某些方法,引入鸭子类型。有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
包装在另一个公开方法的类中
直接你可以摆脱类似指针的行为,但我不想让概念验证复杂化。