From: Leigh Johnston on 22 Dec 2009 20:55 VC9 allows you to modify a std::set and a std::multiset's elements. This seems to be forbidden by the c++0x standard, so is this being fixed in VC10 or left as it is in order not to break software which is c++03 standard's compliant (debatable) but not c++0x standard's compliant? /Leigh
From: David Wilkinson on 23 Dec 2009 07:39 Leigh Johnston wrote: > > VC9 allows you to modify a std::set and a std::multiset's elements. > This seems to be forbidden by the c++0x standard, so is this being fixed > in VC10 or left as it is in order not to break software which is c++03 > standard's compliant (debatable) but not c++0x standard's compliant? Following code compiles on VC9 but not VC10: #include <set> class A { int m_n; public: A(int n):m_n(n){} void Change(){m_n++;} bool operator < (const A& rhs) const {return m_n < rhs.m_n;} }; int main() { std::set<A> mySet; A a(1); mySet.insert(a); mySet.begin()->Change(); return 0; } Error message on VC10 is error C2662: 'A::Change' : cannot convert 'this' pointer from 'const A' to 'A &' Conversion loses qualifiers. So it seems this is fixed in VC10. Code compiles on VC10 if you make A::m_n mutable and A::Change() const, but this will break the set. This trick could be used to make inconsequential changes (ones that did not change the ordering). -- David Wilkinson Visual C++ MVP
From: Leigh Johnston on 24 Dec 2009 11:57 > > Code compiles on VC10 if you make A::m_n mutable and A::Change() const, > but this > will break the set. This trick could be used to make inconsequential > changes > (ones that did not change the ordering). > I always think mutable is a bit of a hack as const setter functions seem somehow dodgy to me, instead I have just written the following: template <typename T, typename Pr = std::less<typename T::key_type const>, typename Alloc = std::allocator<std::pair<typename T::key_type const, T> > > class mutable_set : public std::map<typename T::key_type, T, Pr, Alloc> { typedef typename T::key_type key_type; typedef std::map<key_type, T, Pr, Alloc> base_type; public: class iterator : public base_type::iterator { public: iterator() {} iterator(typename base_type::iterator aIterator) : base_type::iterator(aIterator) {} T* operator->() const { return &base_type::iterator::operator*().second; } T& operator*() const { return base_type::iterator::operator*().second; } }; class const_iterator : public base_type::const_iterator { public: const_iterator() {} const_iterator(typename base_type::const_iterator aIterator) : base_type::const_iterator(aIterator) {} const T* operator->() const { return &base_type::const_iterator::operator*().second; } const T& operator*() const { return base_type::const_iterator::operator*().second; } }; public: iterator insert(const T& aValue) { return iterator(base_type::insert(std::make_pair(static_cast<key_type>(aValue), aValue)).first); } }; struct foo { struct key_type { bool operator<(const key_type& other) const { return true; } }; operator key_type() const { return key_type(); } }; int main() { mutable_set<foo> s; s.insert(foo()); }
From: Leigh Johnston on 25 Dec 2009 12:10 Take a look at http://i42.co.uk/stuff/mutable_set.htm if you like for my full take on this. /Leigh
From: Stephan T. Lavavej [MSFT] on 4 Jan 2010 14:15 I built a time machine, so I answered your question over half a year ago: http://blogs.msdn.com/vcblog/archive/2009/05/25/stl-breaking-changes-in-visual-studio-2010-beta-1.aspx (Note that #2 and #4 have been reversed.) To add to the story very briefly: Modifying set elements was always considered a squirreley thing to do, so even VC9 had an undocumented and untested option called _HAS_IMMUTABLE_SETS that defaulted to 0. (Don't try to use it! Read on.) While we were rewriting the STL in VC10, I noticed this option and that C++0x mandated set immutability, so I changed its default to 1 (leaving it as an escape hatch). Then I discovered that it didn't actually work - in certain cases, it allowed set elements to be modified anyways. By this point, after seeing several instances of people modifying set elements throughout VS's codebase, I had become completely opposed to modifying set elements (just like C++0x), and I had encountered an ironclad solution to the problem (mentioned in the SCARY iterator proposal). So I made set's iterator be the same type as const_iterator, and removed the _HAS_IMMUTABLE_SETS escape hatch. STL "Leigh Johnston" <leigh(a)i42.co.uk> wrote in message news:%23$$1GM3gKHA.5520(a)TK2MSFTNGP06.phx.gbl... > > VC9 allows you to modify a std::set and a std::multiset's elements. This > seems to be forbidden by the c++0x standard, so is this being fixed in > VC10 or left as it is in order not to break software which is c++03 > standard's compliant (debatable) but not c++0x standard's compliant? > > /Leigh
|
Next
|
Last
Pages: 1 2 Prev: Confused about passing an Array of Objects to a function Next: C++ and VC++ Differences |