C++ 标准:多集中意外的 const_iterator
我最近遇到了一个奇怪的问题,在迭代多重集时我会得到一个 const_iterator
而不是预期的 iterator
.结果证明这对 MSVC 来说不是问题,但 g++ 给了我一个错误:
I recently ran into an odd issue where I'd get a const_iterator
instead of the expected iterator
when iterating through a multiset. It turned out to be a non-issue for MSVC but g++ gave me an error:
错误:初始化无效'myPtr&' 类型的引用从'const 类型的表达式boost::shared_ptr'
error: invalid initialization of reference of type 'myPtr&' from expression of type 'const boost::shared_ptr'
相关代码:
typedef std::multiset<myPtr> myList;
myList _mystuff;
void tick(float dt)
{
for (myList::iterator i = _mystuff.begin(); i != _mystuff.end(); ++i)
{
myPtr &mine = *i; // g++ problem here, not for MSVC
// const myPtr &mine = *i; works fine for g++
mine->tick(dt);
}
}
相当多的研究表明,这是之前大量讨论的问题.我找到了这些相关位:
Quite a bit of research revealed that is a problem with lots of previous discussion. I found these relevant bits:
- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=14990
- http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#322
- http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#103
- http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#279
- http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#528
我的背景知识和对这个问题的把握是有限的,因此我想知道标准是否没有很好地定义这种行为,在这种情况下 g++ 和 MSVC 实现了他们喜欢的行为,或者是 g++ 还是 MSVC偏离明确定义的标准.
My background knowledge and grasp on the issue is limited and thus I'd like to know whether the standard doesn't define this behavior well enough in which case g++ and MSVC implement the behavior to their liking or whether either g++ or MSVC deviate from a well-defined standard.
提前致谢.
推荐答案
set 和 multiset 的迭代器从标准迭代器/const 迭代器对更改为只是 const 迭代器.这种改变的原因是它们是有序的容器,改变迭代器内部的元素实际上可以使这个排序约束失效.
The iterators for set and multiset were changed from the standard iterator/const iterator pair to just being const iterators. The reason for this change was that they are ordered containers, and changing the element inside of an iterator can actually invalidate this ordering constraint.
您正在测试的 GCC 版本进行了此更改,而您使用的 VC 版本没有.VC10(和 VC9 SP1,我相信)总是从集合和多集合返回 const_iterators.
The version of GCC you're testing against has made this change, the version of VC that you're using has not. VC10 (and VC9 SP1, I believe) always return const_iterators from sets and multisets.
C++1x 最新草案的 23.2.4/6(目前为 n3000.pdf)说
23.2.4/6 of the latest draft of C++1x (n3000.pdf at the moment) says
对于关联容器,其中值类型与键相同类型,iterator 和 const_iterator是常量迭代器.
For associative containers where the value type is the same as the key type, both iterator and const_iterator are constant iterators.
std::set 和 std::multi_set 是值类型与键类型相同的关联容器.
std::set and std::multi_set are the associative containers where the value type is the same as the key type.
相关文章