Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/153.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++_Iterator_Comparison Operators_Const Iterator - Fatal编程技术网

C++ 常量迭代器与迭代器的比较是否定义良好?

C++ 常量迭代器与迭代器的比较是否定义良好?,c++,iterator,comparison-operators,const-iterator,C++,Iterator,Comparison Operators,Const Iterator,考虑以下代码: #include <vector> #include <iostream> int main() { std::vector<int> vec{1,2,3,5}; for(auto it=vec.cbegin();it!=vec.cend();++it) { std::cout << *it; // A typo: end instead of cend if

考虑以下代码:

#include <vector>
#include <iostream>

int main()
{
    std::vector<int> vec{1,2,3,5};
    for(auto it=vec.cbegin();it!=vec.cend();++it)
    {
        std::cout << *it;
        // A typo: end instead of cend
        if(next(it)!=vec.end()) std::cout << ",";
    }
    std::cout << "\n";
}
#包括
#包括
int main()
{
std::向量向量向量{1,2,3,5};
对于(自动it=vec.cbegin();it!=vec.cend();++it)
{

C++11标准第23.2.1节中的std::cout表96为任何容器类型
X
(包括
std::vector
)定义了
a.cend()
的操作语义,如下所示:

const_cast<X const &>(a).end()
const_cast(a).end()
因此答案是肯定的,因为根据这个定义,
cend()
引用了容器中与
end()
相同的元素/位置,
X::iterator
必须可转换为
X::const_iterator
(同一个表(&ast;)中也指定了一个要求)

(对于
begin()


(&ast;)在对其他答案的评论中指出,可兑换性并不一定意味着比较操作
i1==i2
将始终有效,例如,如果
operator==()
是迭代器类型的成员函数,隐式转换只接受右侧参数,而不接受左侧参数。24.2.5/6状态(关于前向迭代器
a
b
):

如果
a
b
都是可取消引用的,那么
a==b
当且仅当
*a
*b
绑定到同一对象时


即使迭代器
end()
cend()
不可取消引用,上面的语句也暗示
operator==()
的定义必须确保即使
a
是常量迭代器而
b
不是常量迭代器,也可以进行比较,反之亦然,因为24.2.5一般都是关于前向迭代器的,包括常量和非常量版本——这一点很清楚,例如从24.2.5/1开始。这就是为什么我相信表96中的措辞,它指的是可兑换性,也意味着可比性。但正如CPPNearner@后面的回答中所述,这一点仅在C++14中明确说明。

参见§23.2.1,表96:

[……]

满足正向迭代器要求的任何迭代器类别

可转换为
X::const\u迭代器


所以,是的,它定义得很好。

令人惊讶的是,C++98和C++11没有说可以将
迭代器与
常量迭代器进行比较。这导致了和。现在在C++14中,§23.2.1[容器.要求.概述]第7页明确允许这样做

在表达中

i == j
i != j
i < j
i <= j
i >= j
i > j
i - j
i==j
i!=j
ij
i-j
其中
i
j
表示容器的
迭代器类型的对象,或者
两者都可以由容器的
常量迭代器的对象替换
类型引用相同的元素,语义没有变化


可转换并不意味着可比较。例如,可转换并不排除作为成员函数实现的比较运算符,这意味着
i
解析为
i.operator@hvd:幸运的是,在提问者的代码中,const_迭代器位于比较的左侧,而普通迭代器位于右侧。因此它被转换。或者我想我们可以说这是不幸的,因为这意味着编译器没有捕捉到
end()的意外使用
@SteveJessop这只是一个例子。另一个是完全不接受
常量迭代器的运算符,而只是
常量迭代器
可以隐式转换为的运算符,需要两个用户定义的转换。第三个是模板比较运算符,其中类型参数由于
转换而无法推导st_迭代器
/
迭代器
不匹配。(幸运的是,现在有一个答案显示了标准中的附加要求。)这只意味着来自与
容器
概念匹配的同一对象的常量迭代器和非常量迭代器可以安全地进行比较。但是,对于其他迭代器,您无法做出这种假设。
i == j
i != j
i < j
i <= j
i >= j
i > j
i - j