繁体   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