C++ 运算符的实现!=国际热核聚变实验堆级
基于的实现,我很难理解C++ 运算符的实现!=国际热核聚变实验堆级,c++,c++11,C++,C++11,基于的实现,我很难理解操作符=并且不明白为什么它不检查\u p\u vec 这是操作符的建议实现= class Iter { public: Iter (const IntVector* p_vec, int pos) : _pos( pos ) , _p_vec( p_vec ) { } // these three methods form the basis of an iterator for use with /
操作符=代码>并且不明白为什么它不检查\u p\u vec
这是操作符的建议实现=仅比较\u pos
的代码>
class Iter
{
public:
Iter (const IntVector* p_vec, int pos)
: _pos( pos )
, _p_vec( p_vec )
{ }
// these three methods form the basis of an iterator for use with
// a range-based for loop
bool operator!= (const Iter& other) const
{
return _pos != other._pos;
}
...
...
private:
int _pos;
const IntVector *_p_vec;
};
然而,我认为正确的方法如下。换句话说,我们必须比较\u pos
和\u p\u vec
bool Iter::operator!= (const Iter& other) const
{
return _p_vec != other._p_vec || _pos != other._pos;
}
问题>谁的代码是正确的
==更新std::vector在比较迭代器时的工作方式====
std::vector<int> vecOne { 1, 2, 3};
std::vector<int> vecTwo { 4, 5, 6};
auto iterOne = vecOne.begin();
std::advance(iterOne, 1);
auto iterTwo = vecTwo.begin();
std::advance(iterTwo, 1);
if ( iterOne == iterTwo)
std::cout << "iterOne == iterTwo" << std::endl;
else
std::cout << "iterOne != iterTwo" << std::endl;
输出为:foo.begin()==bar.begin()
GCC(4.7.1版)比较底层容器引用也是一种改进,以确保两个不同容器的begin()
迭代器比较相等
但是,很少比较不同容器的迭代器(当使用STL算法时,它们永远不会进行比较)。所以这可能被认为是一种优化。设想一个循环,在该循环中,您从begin()
步进到end()
,因此您要比较的唯一迭代器是“当前”迭代器和end()
,它们属于同一个容器
比较标准容器(向量等)的迭代器被认为是未定义的行为。事实上,由于它们从未在(好的)代码(例如标准算法)中进行比较,因此不必为此类情况定义行为
因此,这个Iter
类的作者可能也想回到这一点,并说:“比较不同向量的迭代器是未定义的行为。”
这就是说,如果您想确保从不比较不同容器的迭代器,请忽略此检查,并可能为调试构建断言它(但不要在发布构建中检查它)
比较不同容器的迭代器的一个很好的例子是链表,在链表中定义列表的末尾为空指针(或指向静态空项实例的指针)。将迭代器视为指向链表项的指针;在本例中,end()
迭代器只是一个空指针(或指向此空项)。对于所有容器都是相同的,因此在这种情况下不能在比较方法中实现检查。可能这就是为什么没有定义这种比较的原因之一——在比较不同列表的结束迭代器时,它应该返回“不等”,但不能返回。“比较底层容器引用也是一种改进,以确保两个不同容器的begin()
迭代器的比较相等。”
但是,很少比较不同容器的迭代器(当使用STL算法时,它们永远不会进行比较)。所以这可能被认为是一种优化。设想一个循环,在该循环中,您从begin()
步进到end()
,因此您要比较的唯一迭代器是“当前”迭代器和end()
,它们属于同一个容器
比较标准容器(向量等)的迭代器被认为是未定义的行为。事实上,由于它们从未在(好的)代码(例如标准算法)中进行比较,因此不必为此类情况定义行为
因此,这个Iter
类的作者可能也想回到这一点,并说:“比较不同向量的迭代器是未定义的行为。”
这就是说,如果您想确保从不比较不同容器的迭代器,请忽略此检查,并可能为调试构建断言它(但不要在发布构建中检查它)
比较不同容器的迭代器的一个很好的例子是链表,在链表中定义列表的末尾为空指针(或指向静态空项实例的指针)。将迭代器视为指向链表项的指针;在本例中,end()
迭代器只是一个空指针(或指向此空项)。对于所有容器都是相同的,因此在这种情况下不能在比较方法中实现检查。也许这就是为什么没有定义这种比较的原因之一——在比较不同列表的结束迭代器时,它应该返回“不等”,但不能。作为一般规则,迭代器的用户不应该比较来自不同容器的迭代器。在标准库中,这样做是未定义的行为
因此,假设您只尝试创建与标准库迭代器一样健壮的迭代器,则不需要比较容器。然而,如果您有指向容器的指针,那么至少在调试中检查容器是否匹配是礼貌的,然后声明您不应该进行这种比较
您也可以在发行版中自由地检查它,但如果您使用代码的迭代器也应该使用标准容器,则不建议依赖不同容器中的迭代器来比较not equal
有关未定义行为的讨论,请参见。作为一般规则,迭代器的用户不应比较来自不同容器的迭代器。在标准库中,这样做是未定义的行为
因此,假设您只尝试创建与标准库迭代器一样健壮的迭代器,则不需要比较容器。然而,如果您有指向容器的指针,那么至少在调试中检查容器是否匹配是礼貌的,然后声明您不应该进行这种比较
您也可以在发行版中自由地检查它,但如果您使用代码的迭代器也应该使用标准容器,则不建议依赖不同容器中的迭代器来比较not equal
请参阅,以便有人讨论它如何是未定义的行为。您无需进行检查,因为比较两个不同容器中的迭代器是非常困难的。。。(阿福)你确定吗?比林
std::vector<int> foo;
std::vector<int> bar;
if ( foo.begin() == bar.begin() )
std::cout << "foo.begin() == bar.begin()" << std::endl;
else
std::cout << "foo.begin() != bar.begin()" << std::endl;