[英]Error indicator for std::iterator
我需要一個很好的std::string::npos
std::iterator
,它與“最后一個有效地址之后的下一個位置”( end
)沒有關系。
這里是一些背景:
我有一個方法,在這里我需要在兩個迭代器之間找到一個確定的值,並將迭代器返回到它的下一個位置NEXT(它可以是也可以不是end
)。 可能會發生方法調用只是一個虛擬對象而無需執行任何操作的情況-在這種情況下,我們僅返回begin
。 我還需要一些跡象表明我們無法找到有問題的價值,這就是問題的症結所在:我不知道如何指出這一點。
這是一個簡單的示例:
class FinderClass
{
public:
FinderClass(uint8_t* byte): byte_(byte) {}
std::iterator findEndOfFrame(std::iterator begin, std::iterator end)
{
if (byte_ == NULL)
{
return byte_;
}
std::iterator result = std::find(begin, end, *byte_);
if (result != end)
{
return ++result;
}
return ???;
}
private:
uint8_t* byte_;
}
在某些地方,我們可以這樣使用它:
std::vector<uint8_t> myVector;
myVector.push_back(1);
myVector.push_back(2);
myVector.push_back(3);
uint8_t val = 2;
FinderClass finder(&val);
std::iterator result = finder.findEndOfFrame(myVector.begin(), myVector.end());
if (/* no error */)
{
size_t len = std::distance(myVector.begin(), result);
}
在這種情況下, len
期望值為2。如果val
的值設置為3
期望結果將為3,並且在出現4錯誤的情況下。 只有在構造函數中提供NULL時,才是0
的適當結果。
請記住,這是更為復雜的體系結構的非常簡化的版本。 實際上,我不能簡單地檢查構造函數中提供的內容,因為它是由多個抽象層分隔開的,並且真正的FinderClass
實現了一個接口(這是非常奇怪的實現,因為在其他實現中, byte_
NULL值沒有選擇) 。 在我們稱為std::distance
的點上,只有指向超類的指針可用。
我也不使用std::iterator
本身,而是使用派生類,但是由於std::iterator
沒有定義某種npos
值,因此我認為可能有充分的理由,所以我沒有這樣做我自己也是。 為了簡單起見,我在此示例中僅使用了std::iterator
。
總結一下 :如果end
不能用來表示錯誤,那么應該用什么代替呢?
幾個注意事項:
std::iterator
的指針,並僅在錯誤時返回NULL)被視為“核選項,因為它將需要更新許多其他實現及其單元測試。 給定約束,我要么返回boost::optional<Iterator>
要么指向下一個元素的指針(在這種情況下,如果沒有下一個元素,則可以返回NULL
)。
當然, optional
是更具表現力和更安全的方法,並且不需要花太多時間就能將結果轉換回迭代器。
使用迭代器的代碼通常(實際上可以說是)與迭代器的實際類型無關,而只是期望通過粗略地遞增和解引用運算符來實現。 您無需指定迭代器是否必須為特定類型,如果不是,則相對容易返回圍繞實際矢量迭代器的包裝,該向量本身實現迭代器行為以及具有無效狀態的其他功能。 正如在其他答案中所說的那樣,如果可能的話,選擇optional <>可能是一個更好的選擇,因為它清楚地表達了您的實際含義。 無論如何,偽代碼:
//template argument is the actual iterator type
template< class Iter >
class iterator : std::iterator< Iter::iterator_category,
Iter::value_type, .... >
{
public:
enum tag { invalid_tag };
//construct the invalid 'error' iterator
iterator( invalid_tag ) :
error( true )
{}
//construct actual iterator
iterator( Iter iter ) :
error( false ),
iter( iter )
{}
//forward all functions
reference operator * ()
{
assert( valid() );
return *iter;
}
....
//check validity
bool valid() const
{
return !error;
}
private:
bool error;
Iter iter;
};
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.