将 const_iterator 分配给迭代器
Assigning a const_iterator to an iterator
我有以下代码片段(您可以在此处运行:http://coliru.stacked-crooked.com/a/2f62134b5c125051)
#include <iostream>
#include <set>
#include <map>
int main()
{
std::set<std::pair<const int, const int>> const mySet{{0,0}}; // value_type = std::pair<const int, const int>
for (std::set<std::pair<const int, const int>>::iterator it = mySet.cbegin(); it != mySet.cend(); ++it)
{
std::cout<<"set it = " << it->first << " " << it->second << std::endl;
}
std::map<const int, const int> const myMap{{0,0}}; // value_type = std::pair<const int, const int>
for (std::map<const int, const int>::iterator it = myMap.cbegin(); it != myMap.cend(); ++it)
{
std::cout<<"map it = " << it->first << " " << it->second << std::endl;
}
}
有人可以解释一下为什么 std::set 下面没有抛出任何错误:
std::set<std::pair<const int, const int>>::iterator it = mySet.cbegin();
而对于 std::map 下面抛出错误(没有从 _Rb_tree_const_iterator > 到 _Rb_tree_iterator > ) 如预期:
std::map<const int, const int>::iterator it = myMap.cbegin();
它如何用于 std::set?将 const_iterator 分配给 迭代器 不应该总是抛出错误吗?
实际上 std::set<T>::iterator
与 std::set<T>::const_iterator
相同,因为 std::set
的元素是不可变的。它没有可变迭代器类型。
std::map
情况并非如此,这就是您观察到不同行为的原因。
您不能修改集合元素。键必须是 const
以确保 set
承诺的不变量:元素已排序且唯一。 map
s 元素也已排序,但您可以修改元素的映射值(键也是 const
)。 std::map<A,B>
的元素是 std::pair<const A,B>
.
在 cppreference 上,您可以看到 std::set
的迭代器的成员别名是
iterator Constant LegacyBidirectionalIterator
const_iterator Constant LegacyBidirectionalIterator
它们都是 const 迭代器。
另一方面 std::map
他们是:
iterator LegacyBidirectionalIterator
const_iterator Constant LegacyBidirectionalIterator
将 const_iterator
分配给 non-const 是错误的。这就像试图通过将指向 const
的指针分配给指向 non-const 的指针来强制转换 const
一样。它不会起作用,因为您不能使无法修改的东西变为可修改的。那会破坏 const-correctness.
来自 C++ 17 标准(26.2.6 关联容器)
6 iterator of an associative container is of the bidirectional
iterator category. For associative containers where the value type is
the same as the key type, both iterator and const_iterator are
constant iterators. It is unspecified whether or not iterator and
const_iterator are the same type.
我有以下代码片段(您可以在此处运行:http://coliru.stacked-crooked.com/a/2f62134b5c125051)
#include <iostream>
#include <set>
#include <map>
int main()
{
std::set<std::pair<const int, const int>> const mySet{{0,0}}; // value_type = std::pair<const int, const int>
for (std::set<std::pair<const int, const int>>::iterator it = mySet.cbegin(); it != mySet.cend(); ++it)
{
std::cout<<"set it = " << it->first << " " << it->second << std::endl;
}
std::map<const int, const int> const myMap{{0,0}}; // value_type = std::pair<const int, const int>
for (std::map<const int, const int>::iterator it = myMap.cbegin(); it != myMap.cend(); ++it)
{
std::cout<<"map it = " << it->first << " " << it->second << std::endl;
}
}
有人可以解释一下为什么 std::set 下面没有抛出任何错误:
std::set<std::pair<const int, const int>>::iterator it = mySet.cbegin();
而对于 std::map 下面抛出错误(没有从 _Rb_tree_const_iterator
std::map<const int, const int>::iterator it = myMap.cbegin();
它如何用于 std::set?将 const_iterator 分配给 迭代器 不应该总是抛出错误吗?
实际上 std::set<T>::iterator
与 std::set<T>::const_iterator
相同,因为 std::set
的元素是不可变的。它没有可变迭代器类型。
std::map
情况并非如此,这就是您观察到不同行为的原因。
您不能修改集合元素。键必须是 const
以确保 set
承诺的不变量:元素已排序且唯一。 map
s 元素也已排序,但您可以修改元素的映射值(键也是 const
)。 std::map<A,B>
的元素是 std::pair<const A,B>
.
在 cppreference 上,您可以看到 std::set
的迭代器的成员别名是
iterator Constant LegacyBidirectionalIterator
const_iterator Constant LegacyBidirectionalIterator
它们都是 const 迭代器。
另一方面 std::map
他们是:
iterator LegacyBidirectionalIterator
const_iterator Constant LegacyBidirectionalIterator
将 const_iterator
分配给 non-const 是错误的。这就像试图通过将指向 const
的指针分配给指向 non-const 的指针来强制转换 const
一样。它不会起作用,因为您不能使无法修改的东西变为可修改的。那会破坏 const-correctness.
来自 C++ 17 标准(26.2.6 关联容器)
6 iterator of an associative container is of the bidirectional iterator category. For associative containers where the value type is the same as the key type, both iterator and const_iterator are constant iterators. It is unspecified whether or not iterator and const_iterator are the same type.