[英]Custom container range-based iteration
我有一個自定義容器,我想在基於范圍的for循環中使用它。 容器有點基於向量,如下所示:
template<typename T>
class IDMap
{
private:
struct Item {
uint16_t mVersion;
T mItem;
template <typename... Arguments>
Item(uint16_t version, Arguments&&... args) : mVersion(version), mItem(args...)
{
}
};
public:
typedef uint32_t ItemID;
template <typename... Arguments>
ItemID AddItem(Arguments&&... args);
void MarkAsFree(const ItemID id);
T& GetItem(const ItemID id);
T* TryGetItem(const ItemID id);
void Clear();
private:
std::vector<Item> mItems;
std::vector<uint16_t> mFreeIndices;
};
我想迭代mItems
向量,但只返回mItem
成員而不是整個Item
結構。 有沒有簡單/優雅的方法來做到這一點?
你必須提供一個begin
和end
函數,它們都返回一個相應的迭代器,它本身實現了運算符++
, !=
和*
。 begin
和end
功能可以是獨立的或作為成員。
首先實現具有所需行為的迭代器。 您可以將其實現為std::vector::iterator
的包裝std::vector::iterator
以保存大部分“核心”工作。
以下是未經測試的代碼
基本上,在類IDMap中,添加:
class ItemIterator {
// based on vector iterator
std::vector<Item>::iterator i;
public:
ItemIterator(std::vector<Item>::iterator i) : i(i) {}
// incrementing
ItemIterator & operator ++() { ++i; return *this; }
ItemIterator operator ++(int) { const_iterator old(*this); ++(*this); return old; }
// comparison
bool operator!=(const ItemIterator &o) const { return i != o.i; }
// dereferencing
const T & operator*() const { return i->mItem; }
};
using iterator = ItemIterator;
using value_type = T;
ItemIterator begin() const { return ItemIterator(mItems.begin()); }
ItemIterator end() const { return ItemIterator(mItems.end() ); }
如果你想在你的IDMap上支持多種“特殊迭代”,例如在索引上,或在“整個” Item
,你應該將所有內容包裝在另一個適配器中。 然后可以使用成員方法訪問此適配器,如.items()
。
簡要示例:
class IDMap {
// (your code)
public:
struct ItemsAdaptor {
// (insert above iterator definition + usings)
ItemsAdaptor(std::vector<Item>::iterator b,
std::vector<Item>::iterator e)
: b{b}, e{e}
{}
ItemIterator begin() const { return b; }
ItemIterator end() const { return e; }
private:
ItemIterator b, e;
};
ItemsAdaptor items() const {
return ItemsAdaptor(mItems.begin(), mItems.end());
}
};
然后,你可以寫:
IDMap<int> map = ...;
for (int i : map.items()) {
...
}
如果希望基於范圍的for適用於容器,則必須提供返回前向迭代器的開始和結束函數。
typedef std::vector<Item>::iterator iterator;
typedef std::vector<Item>::const_iterator const_iterator;
iterator begin()
{
return mItems.begin();
}
const_iterator begin() const;
{
return mItems.begin();
}
//also add end functions, and viola.
這將返回整個項結構。 如果你只需要返回mItem,你必須編寫自己的迭代器適配器並使用它而不是vector。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.