[英]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.