-
Notifications
You must be signed in to change notification settings - Fork 15.3k
Description
| Bugzilla Link | 34898 |
| Resolution | FIXED |
| Resolved on | Nov 22, 2017 07:06 |
| Version | 5.0 |
| OS | Linux |
| Blocks | #33840 |
| CC | @mclow,@tstellar |
| Fixed by commit(s) | r315994 r318837 |
Extended Description
Example:
=====
template
class Iterator : public boost::iterator_facade<Iterator, Base, CategoryT> {
friend class boost::iterator_core_access;
void increment();
bool equal(Iterator const& other) const;
typename Iterator::reference dereference() const;
};
void foo() {
using ForwardIt = Iteratorstd::forward_iterator_tag;
std::vector x1(ForwardIt{}, ForwardIt{});
using InputIt = Iteratorstd::input_iterator_tag;
std::vector x2(InputIt{}, InputIt{}); // ERROR
}
The example is a bit complex, but the upshot is that std::vector::vector(Iterator, Iterator) uses push_back() only for input iterators. This is in contrast with forward iterators or greater, which use emplacement, and thus consider the explicit constructors.
The standard would indicate that libc++'s InputIterator behaviour is correct. Specifically, it gives this example:
X(i, j)
Requires: T shall be EmplaceConstructible into X from *i. [...]
with the constraint:
"... i and j denote iterators satisfying input iterator requirements and refer to elements implicitly convertible to value_type ..."
https://timsong-cpp.github.io/cppwp/n4659/container.requirements#sequence.reqmts-3
This means that constructing a vector from iterator inputs, and using explicit constructors, is undefined behaviour.