我想要做的是返回一个 ForwardIterator(甚至是一对开始和结束迭代器),以便可以对客户端类隐藏底层实现。我找不到任何这样的例子。
如果底层实现是向量,则迭代器是 vector::iterator.. 即使您将输出模板化,这似乎也不起作用。
您不能同时按原样返回对象并期望调用者不知道其类型。“隐藏”任何对象的真实类型的典型方法是将其隐藏在接口后面。
例如,您可能想编写如下内容:
template<typename T>
class Cursor
{
public:
typedef T value_type;
virtual ~Cursor () {}
virtual bool has_result () = 0;
virtual value_type get_result () = 0;
};
// implements cursor interface for any sequence
// described as a pair of forward iterators.
template<typename I>
class ForwardSequenceCursor :
public Cursor<std::iterator_traits<I>::value_type>
{
I myCurrent;
const I myEnd;
public:
ForwardSequenceCursor(I begin, I end)
: myCurrent(current), myEnd(end)
{}
virtual bool has_result () {
return myCurrent != myEnd;
}
virtual value_type get_result () {
return *myCurrent++;
}
};
然后,您可以将任何正向序列返回为:
class Foo
{
std::vector<int> myValues;
public:
std::unique_ptr< Cursor<int> > values () {
return std::unique_ptr< Cursor<int> >(
new ForwardSequenceCursor<vector<int>::const_iterator>(
myValues.begin(), myValues.end()
)
);
}
};
并像这样使用它:
std::unique_ptr< Cursor<int> > cursor = foo.values();
while (cursor->has_result()) {
std::cout << cursor->get_result() << std::endl;
}
您正在寻找的是“迭代器的类型擦除”。例如,参见以下之一:
你不能直接做你想做的事情,因为正如其他人所提到的,如果你的客户要获得一个返回值,它需要知道那个返回值是什么。
一种解决方法是执行以下操作:
template<typename Collection> class MyClass
{
typedef Collection::iterator ReturnIt;
typedef std::pair<ReturnIt, ReturnIt> IteratorPair;
ReturnIt foo();
IteratorPair bar();
};
现在,这并没有让我们从客户端看到容器类型中解放出来,但是接口没有绑定到容器类型。
ForwardIterator 是一个概念,而不是一个类型。您需要声明您的函数以返回一个类型。
没有“ForwardIterator”类型的基类,正常的 STL 方法是在你的类中有一个实际迭代器类型的 typedef,以便客户端代码可以像这样使用它:
MyClass::iterator it = myclass.begin();
隐藏起来不是很好,但仍然可以让您稍后更改实现而无需更改客户端代码。