簡體   English   中英

std :: iterator的錯誤指示器

[英]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不能用來表示錯誤,那么應該用什么代替呢?

幾個注意事項:

  1. 團隊的編碼標准禁止例外
  2. 接口的更改(例如,將返回的值更改為指向std::iterator的指針,並僅在錯誤時返回NULL)被視為“核選項,因為它將需要更新許多其他實現及其單元測試。
  3. C ++ 11不可用

給定約束,我要么返回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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM