| Summary: | vector::insert_range should not use ranges::copy | ||
|---|---|---|---|
| Product: | gcc | Reporter: | 康桓瑋 <hewillk> |
| Component: | libstdc++ | Assignee: | Not yet assigned to anyone <unassigned> |
| Status: | NEW --- | ||
| Severity: | normal | CC: | daniel.kruegler, hubicka, webrown.cpp |
| Priority: | P3 | ||
| Version: | 15.0 | ||
| Target Milestone: | --- | ||
| Host: | Target: | ||
| Build: | Known to work: | ||
| Known to fail: | Last reconfirmed: | 2024-11-13 00:00:00 | |
| Bug Depends on: | |||
| Bug Blocks: | 118130, 111055 | ||
ranges::copy performs exactly the same operations as vector::insert(p, i, j) does, which fails the same way for libstdc++ and libc++:
std::vector<Int> v;
std::vector<int> vi{42};
v.insert(v.begin(), vi.begin(), vi.end());
So this seems like a pre-existing issue. Arguably, it's a standard defect. Why should be construct new elements when we already have some in the right locations?
MSVC creates a hole in the middle of the vector, destroying the elements that were there previously, then fills the hole using uninitialized_copy. |
Unlike vector::assign_range which requires assignable_from<T&, ranges::range_reference_t<R>> is true, this means that ranges::copy is not necessarily well-formed for vector::insert_range: #include <vector> struct Int { void operator=(int) = delete; Int(int); }; int main() { std::vector<Int> v; v.insert_range(v.begin(), std::vector{42}); } https://godbolt.org/z/jo3vjjo5b