听起来不太复杂。您可以在外部定义迭代器。您还可以使用 typedef。我认为这样的东西会适合。请注意,如果 MagicIterator不是免费模板,而是 Item 的成员,可能会在 Container 中进行类型定义,这样会更简洁。就像现在一样,其中有一个循环引用,这使得编写一些丑陋的解决方法代码变得很有必要。
namespace detail {
template<typename T, typename U>
struct constify;
template<typename T, typename U>
struct constify<T*, U*> {
typedef T * type;
};
template<typename T, typename U>
struct constify<T*, U const*> {
typedef T const * type;
};
}
template<typename DstType,
typename Container,
typename InputIterator>
struct MagicIterator;
class Container
{
private:
struct Item
{
Object* pObject;
};
std::list<Item> m_items;
public:
// required by every Container for the iterator
typedef std::list<Item> iterator;
typedef std::list<Item> const_iterator;
// convenience declarations
typedef MagicIterator< IInterface*, Container, iterator >
item_iterator;
typedef MagicIterator< IInterface*, Container, const_iterator >
const_item_iterator;
item_iterator Begin();
item_iterator End();
};
template<typename DstType,
typename Container = Container,
typename InputIterator = typename Container::iterator>
struct MagicIterator :
// pick either const T or T, depending on whether it's a const_iterator.
std::iterator<std::input_iterator_tag,
typename detail::constify<
DstType,
typename InputIterator::value_type*>::type> {
typedef std::iterator<std::input_iterator_tag,
typename detail::constify<
DstType,
typename InputIterator::value_type*>::type> base;
MagicIterator():wrapped() { }
explicit MagicIterator(InputIterator const& it):wrapped(it) { }
MagicIterator(MagicIterator const& that):wrapped(that.wrapped) { }
typename base::value_type operator*() {
return (*wrapped).pObject->GetInterface();
}
MagicIterator& operator++() {
++wrapped;
return *this;
}
MagicIterator operator++(int) {
MagicIterator it(*this);
wrapped++;
return it;
}
bool operator==(MagicIterator const& it) const {
return it.wrapped == wrapped;
}
bool operator!=(MagicIterator const& it) const {
return !(*this == it);
}
InputIterator wrapped;
};
// now that the iterator adepter is defined, we can define Begin and End
inline Container::item_iterator Container::Begin() {
return item_iterator(m_items.begin());
}
inline Container::item_iterator Container::End() {
return item_iterator(m_items.end());
}
现在,开始使用它:
for(MagicIterator<IInterface*> it = c.Begin(); it != c.End(); ++it) {
// ...
}
您还可以使用 boost 提供的迭代器 mixin,其工作方式类似于 boost::function_output_iterator 的输入版本。它调用您的迭代器operator()
,然后返回适当的值,按照我们operator*
的原则执行上述操作。你在random/detail/iterator_mixin.hpp
. 这可能会导致更少的代码。但它也需要我们绞尽脑汁来确保朋友的东西,因为 Item 是私有的,并且迭代器没有在 Item 中定义。无论如何,祝你好运:)