Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/135.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么默认构造的迭代器可以用于单过程结束标志?_C++_Boost - Fatal编程技术网

C++ 为什么默认构造的迭代器可以用于单过程结束标志?

C++ 为什么默认构造的迭代器可以用于单过程结束标志?,c++,boost,C++,Boost,如您所见,为每个元素传递给的结束迭代器的过去时间 regex_迭代器的默认构造实例 问题>既然端与任何容器都没有关联,那么std::for_each如何将其用作容器的单端标志 谢谢好的,对的描述是: 假设next()的伪codey定义可能会出现以下情况: 或者: void boost::regex_iterator::next() { this->ptr++; if (this->ptr == this->original_defined_end_ptr) {

如您所见,为每个元素传递给的结束迭代器的过去时间 regex_迭代器的默认构造实例

问题>既然
与任何容器都没有关联,那么
std::for_each
如何将其用作容器的单端标志

谢谢

好的,对的描述是:

假设next()的伪codey定义可能会出现以下情况:

或者:

void boost::regex_iterator::next() {
    this->ptr++;
    if (this->ptr == this->original_defined_end_ptr) {
         this = regex_iterator();
    } else {
         ...
    }
}
或许:

class regex_iterator:
    regex_iterator():
        this->only_true_when_compared_to_end_iterator = true

    regex_iterator(begin, end):
        this->only_true_when_compared_to_end_iterator = false
        this->cur = begin
        this->end = end

    operator==(other):
        if this->only_true_when_compared_to_end_iterator:
             return other->cur == other->end
        if other->only_true_when_compared_to_end_iterator:
             return this->cur == this->end
        return this->cur == other->cur

    next():
        this->cur++

这很简单。迭代器
it
以这样的方式递增,即在某一点上它与
end
迭代器相等。它何时变得等于
end
?当迭代器
无法遍历更多项时

由于类
boost::sregex_iterator
知道如何创建默认构造的迭代器
end
,以及它具有什么值,因此它可以给
赋予相同的值,或者给
操作符的实现赋予某些值=用于比较迭代器并推断它们是否不等。这意味着,它还取决于
运算符的定义=

例如,请参见此
range\u iterator
,以演示其基本思想:

class regex_iterator:
    regex_iterator():
        this->cur = 0

    regex_iterator(begin, end):
        this->cur = begin
        this->end = end

    operator==(other):
        return this->cur == other->cur

    next():
        this->cur = this->cur->next()
        if this->cur == this->end:
            this->cur = 0
在线演示:


参见
操作符的实现=
和默认构造函数;它们是如何一起工作的,以及
操作符是如何工作的=推断迭代器是否不等。这是一个非常简单的实现。我知道这个类可以用很多不同的方式实现。但是迭代器的等式和不等式的基本思想是相同的

需要注意的一点是,这不是一种普遍的行为。 在标准中,默认构造的迭代器充当“end” 用于iostream迭代器的迭代器,但不用于 容器。通常,这个习惯用法用于输入迭代器或其他 之前无法知道序列结束的情况 实际上是在读。
boost::regex
的作者决定遵循
boost::sregex_迭代器的此约定;当然没有
要求他们这样做。但事实是,虽然它是一个前锋
迭代器,通常不可能知道终点在哪里,除非
试着前进到它,这样使用似乎是合理的

对于输入迭代器,“等于”的定义 是相当松散的,所需要的只是迭代器 定义为“end”的比较不等于 定义为“结束”;一个简单的
myisattend
标志作为成员,以及

10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 

这可能足够了。因为
boost::sregex_迭代器
是向前的 迭代器,而不仅仅是输入迭代器,约束在某种程度上是 更严格,但可以很容易地将上述内容包括在内,例如 如下所示:

bool
IteratorType::operator==( IteratorType const& other ) const
{
    return myIsAtEnd && other.myIsAtEnd;
}
默认构造函数只是将
myisattend
设置为true。(另一个 您使用的构造函数将首先尝试查找第一个匹配项,然后 将系统地将MyIsAttend设置为是否找到匹配项。)

可能值得指出的是,Boost通常会通过 迭代器。标准迭代器的概念或多或少被打破了(因为 它需要两个对象,而不是一个),这是一个或多或少的问题 解决这个问题的标准习惯用法。你会发现它被广泛应用于
boost::iterator
同样适用于过滤迭代器之类的东西

问题>由于端部与任何容器都没有关联,std::for\ U如何将其用作容器的单向端标志

迭代器根本不必与任何容器相关联。一个例子是流迭代器,它从一些源读取输入,比如控制台(可能是键盘)

这样的迭代器可能包含指向下一个输入源的指针。当到达输入端时(不知何故),可以将该指针设置为NULL。如果默认构造的迭代器也包含空指针,那么它看起来就像一个结束迭代器


std::for_each
不必知道这方面的任何信息。它只调用重载的
操作符=。操作员将知道所比较的两个迭代器是否都是末端迭代器。

我仍然不知道如何设计适用于不同容器的末端迭代器。根据您的示例,我们如何在占用不同内存空间的不同容器之间共享相同的
原始\u定义的\u结束\u ptr
。@q0987:您不能。但是,您可以设计一个容器,它返回一个与所有其他末端迭代器进行比较的末端迭代器。关键是我们如何在不同的容器之间共享末端迭代器。@q0987:不同的容器意味着不同的
类型
?不,它不能在不同类型之间共享。我指的是同一容器类型的不同实例。由于不同的实例使用不同的内存空间,我很难想象我们如何在所有不同的实例中使用共享端。@q0987:请参见我的编辑。特别要看
操作符的实现=和默认构造函数。
struct range_iterator
{
       int lower_, upper_;
       range_iterator() : upper_(0), lower_(0) 
       {}
       range_iterator(int lower, int upper) : upper_(upper), lower_(lower) 
       {}
       int operator*(){ return lower_; }
       int operator++(){ lower_++; }

       bool operator != (range_iterator const & other)
       {
           return (upper_-lower_) != (other.upper_-other.lower_);
       }
};

int main()
{
       range_iterator begin(10,25), end;
       while(begin != end)
       {
          std::cout << *begin << std::endl;;
          ++begin;
       }
}
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 
bool
IteratorType::operator==( IteratorType const& other ) const
{
    return myIsAtEnd != other.myIsAtEnd;
}
bool
IteratorType::operator==( IteratorType const& other ) const
{
    return myIsAtEnd && other.myIsAtEnd;
}
bool
boost::sregex_iterator::operator==(
    boost::sregex_iterator const& other )
{
    return myIsAtEnd
        ?  other.myIsAtEnd
        :  (!other.myIsAtEnd
            && myMatchPosition == other.myMatchPosition);
}