Created on 2010-03-28.00:00:00 last changed 162 months ago
Proposed resolution:
The wording refers to N3126.
template <class Container> class back_insert_iterator : public iterator<output_iterator_tag,void,void,void,void> { protected: Container* container; public: [..] back_insert_iterator<Container>& operator=(const typename Container::const_referencevalue_type& value); back_insert_iterator<Container>& operator=(typename Container::value_type&& value); [..] };
back_insert_iterator<Container>& operator=(const typename Container::const_referencevalue_type& value);1 Effects: container->push_back(value);
2 Returns: *this.
template <class Container> class front_insert_iterator : public iterator<output_iterator_tag,void,void,void,void> { protected: Container* container; public: [..] front_insert_iterator<Container>& operator=(const typename Container::const_referencevalue_type& value); front_insert_iterator<Container>& operator=(typename Container::value_type&& value); [..] };
front_insert_iterator<Container>& operator=(const typename Container::const_referencevalue_type& value);1 Effects: container->push_front(value);
2 Returns: *this.
template <class Container> class insert_iterator : public iterator<output_iterator_tag,void,void,void,void> { protected: Container* container; typename Container::iterator iter; public: [..] insert_iterator<Container>& operator=(const typename Container::const_referencevalue_type& value); insert_iterator<Container>& operator=(typename Container::value_type&& value); [..] };
insert_iterator<Container>& operator=(const typename Container::const_referencevalue_type& value);1 Effects:
iter = container->insert(iter, value); ++iter;2 Returns: *this.
[ Adopted at 2010-11 Batavia ]
[ Post-Rapperswil ]
This problem is not restricted to the unspeakable vector<bool>, but is already existing for other proxy containers like gcc's rope class. The following code does no longer work ([Bug libstdc++/44963]):
#include <iostream> #include <ext/rope> using namespace std; int main() { __gnu_cxx::crope line("test"); auto ii(back_inserter(line)); *ii++ = 'm'; // #1 *ii++ = 'e'; // #2 cout << line << endl; }
Both lines marked with #1 and #2 issue now an error because the library has properly implemented the current wording state (Thanks to Paolo Calini for making me aware of this real-life example).
The following P/R is a revision of the orignal P/R and was initially suggested by Howard Hinnant. Paolo verified that the approach works in gcc.
Moved to Tentatively Ready with revised wording after 6 positive votes on c++std-lib.
In C++03 this was valid code:
#include <vector> #include <iterator> int main() { typedef std::vector<bool> Cont; Cont c; std::back_insert_iterator<Cont> it = std::back_inserter(c); *it = true; }
In C++0x this code does no longer compile because of an ambiguity error for this operator= overload pair:
back_insert_iterator<Container>& operator=(typename Container::const_reference value); back_insert_iterator<Container>& operator=(typename Container::value_type&& value);
This is so, because for proxy-containers like std::vector<bool> the const_reference usually is a non-reference type and in this case it's identical to Container::value_type, thus forming the ambiguous overload pair
back_insert_iterator<Container>& operator=(bool value); back_insert_iterator<Container>& operator=(bool&& value);
The same problem exists for std::back_insert_iterator, std::front_insert_iterator, and std::insert_iterator.
One possible fix would be to require that const_reference of a proxy container must not be the same as the value_type, but this would break earlier valid code. The alternative would be to change the first signature to
back_insert_iterator<Container>& operator=(const typename Container::const_reference& value);
This would have the effect that this signature always expects an lvalue or rvalue, but it would not create an ambiguity relative to the second form with rvalue-references. [For all non-proxy containers the signature will be the same as before due to reference-collapsing and const folding rules]
History | |||
---|---|---|---|
Date | User | Action | Args |
2011-08-23 20:07:26 | admin | set | status: wp -> c++11 |
2010-11-24 14:01:03 | admin | set | messages: + msg5424 |
2010-11-14 13:10:57 | admin | set | status: voting -> wp |
2010-11-08 14:14:39 | admin | set | status: ready -> voting |
2010-10-21 19:06:53 | admin | set | messages: + msg4773 |
2010-10-21 19:06:53 | admin | set | status: new -> ready |
2010-10-21 18:28:33 | admin | set | messages: + msg1624 |
2010-03-28 00:00:00 | admin | create |