-
-
The part of the is_writable_iterator trait definition which
-applies to old-style iterators is:
+
The is_writable and is_swappable traits classes in N1550
+provide a mechanism for determining at compile time if an iterator
+type is a model of the new Writable Iterator and Swappable Iterator
+concepts, analogous to iterator_traits<X>::iterator_category
+for the old iterator concepts. For backward compatibility,
+is_writable and is_swappable not only work with new
+iterators, but they also are intended to work for old
+iterators (iterators that meet the requirements for one of the
+iterator concepts in the current standard). In the case of old
+iterators, the writability and swapability is deduced based on the
+iterator_category and also the reference type. The
+specification for this deduction gives false positives for forward
+iterators that have non-assignable value types.
+
To review, the part of the is_writable trait definition which
+applies to old iterators is:
if (cat is convertible to output_iterator_tag)
- return true;
- else if (
- cat is convertible to forward_iterator_tag
+ return true;
+else if (cat is convertible to forward_iterator_tag
and iterator_traits<Iterator>::reference is a
mutable reference)
- return true;
- else
- return false;
-
-
The current forward iterator requirements place no constraints on
-the iterator's reference type, so the logic above will give
-false negatives for some otherwise-writable forward iterators whose
-reference type is not a mutable reference. Also, it will
-report false positives for any forward, bidirectional, or random
-access iterator whose reference is a mutable reference but
-whose value_type is not assignable (e.g. has a private
-assignment operator).
-
-
-
Similarly, the part of is_swappable_iterator which applies to
-old-style iterators is:
-
-else if (cat is convertible to forward_iterator_tag) {
- if (iterator_traits<Iterator>::reference is a const reference)
- return false;
- else
- return true;
-} else
+ return true;
+else
return false;
-
In this case false positives are possible for non-writable forward
-iterators whose reference type is not a reference, or as above,
-any forward, bidirectional, or random access iterator whose
-reference is not a constant reference but whose value_type
-is not assignable (e.g., because it has a private assignment
-operator).
-
False negatives can be "reasoned away": since it is part of a
-writable iterator's concept definition that
-is_writable<I>::value is true, any iterator for which
-it is false is by definition not writable. This seems like a
-perverse use of logic, though.
-
It might be reasonable to conclude that it is a defect that the
-standard allows forward iterators with a reference type other
-than value_type cv&, but that still leaves the problem
-of old-style iterators whose value_type is not assignable. It
-is not possible to correctly compute writability and swappability
-for those old-style iterators without intervention
-(specializations of is_writable_iterator and
-is_swappable_iterator) from a user.
+
Suppose the value_type of the iterator It has a private
+assignment operator:
+
+class B {
+public:
+ ...
+private:
+ B& operator=(const B&);
+};
+
+
and suppose the reference type of the iterator is B&. In
+that case, is_writable<It>::value will be true when in fact
+attempting to write into B will cause an error.
+
The same problem applies to is_swappable.