Date: Mon, 9 Feb 2026 14:24:12 +0800 (GMT+08:00)
Hi Ell,
Sorry for missing your email for not being cc'ed. You're right! I didn't notice such problem and it seems to be already discussed by author of ranges (Validity of references obtained from out-of-lifetime iterators · Issue #156 · ericniebler/stl2). This is a more profound problem that I previously expected.
Again, sorry and much thanks!
Liang Jiaming
From: Ell via Std-Proposals <std-proposals_at_[hidden]>
Date: 2026-02-04 06:40:12
To: std-proposals_at_[hidden]
cc: Ell
Title: Re: [std-proposals] filesystem::path::iterator should be bidirectional_iterator even if it's not Cpp17BidirectionalIterator>On Tuesday, February 3rd, 2026 at 11:18 PM, Arthur O'Dwyer via Std-Proposals <std-proposals_at_[hidden]> wrote:
>
>> On Thu, Jan 29, 2026 at 8:48 PM 梁家铭 via Std-Proposals <std-proposals_at_[hidden]> wrote:
>>
>> > Hi,
>> >
>> > Recently I find that `filesystem::path::iterator` is not bidirectional iterator, as specified in Issue 2674: Bidirectional iterator requirement on path::iterator is very expensive. It fulfills all requirements of Cpp17BidirectionalIterator except that there is no requirement that two equal iterators be bound to the same object (See [fs.class.path]). The reason is that it allows the iterator to cache filename component (as libc++ and MS-STL do) instead of storing a container of components in filesystem::path (as libstdc++ does, unfortunately). However, it also degrades path::iterator from Cpp17BidirectionalIterator to Cpp17InputIterator (well only libstdc++ can and indeed mark it with bidirectional_iterator_tag). Such degradation is also counter-intuitive and makes many components in `<algorithm>` inapplicable (e.g. libc++ issue: https://github.com/llvm/llvm-project/issues/55683).
>> >
>> > However, such simplification is very like `std::views::split`, which makes it fulfill bidirectional_iterator since C++20 if we examine all concepts one by one except the iterator tag. And C++20 allows us to define `iterator_concept` instead of examining `iterator_tag`. So I think we should make a fix DR (bold means wording change):
>> >
>> > A path::iterator is a constant iterator meeting all the requirements of a Cpp17BidirectionalIterator except that, for dereferenceable iterators a and b of type path::iterator with a == b, there is no requirement that *a and *b are bound to the same object.
>> > Its value_type is path. Therefore, it should fulfill concept
>> > bidirectional_iterator.
>> >
>> > And implementations can utilize `iterator_concept` to support it.
>>
>>
>> This sounds to me like a reasonable topic for a paper. I mean, this seems 100% like LEWG design territory — although I admit I'm confused by the existence of LWG 2674 and the implementation divergence between libc++/libstdc++ and Microsoft.
>>
>> I haven't investigated this area myself, so I don't have a concrete suggestion for wording. But the stuff you wrote in green above is not good wording. Don't say something "should" do something; just show the actual diff you're proposing. Find the words in the Standard that are currently as-they-should-not-be, and show how to replace them with something better.
>> You say path::iterator should [sic] "fulfill" concept `bidirectional_iterator`. But that's not a thing. We can say that path::iterator satisfies `bidirectional_iterator`; this is already true on libc++ and libstdc++, but false on MS STL. However, I'm confused by your phrasing — are you saying you want path::iterator to satisfy `bidirectional_iterator` without modeling `bidirectional_iterator`? Doesn't that make lots of usages IFNDR, technically? Obviously such IFNDR-ness would be harmless in practice; but how could WG21 possibly standardize anything along those lines with a straight face — "we provide a library type that satisfies a library concept but doesn't model it"? That way lies madness, it seems to me.
>> Maybe I'm just missing something basic; again, I haven't looked deeply at this at all. But you could help by providing the exact wording you think ought to change, and how to change it.
>>
>
>
>C++20 forward iterators still require returned lvalues to outlive the
>iterator
>(https://eel.is/c++draft/iterator.concepts#iterator.concept.forward-3),
>so they can't both cache the result and return it by reference. libc++
>returns the cached path by value, so it can and does declare
>iterator_concept as bidirectional. Not sure when it was added, OP might
>want to try a newer version. I'm also not sure if dereferencing the
>iterator is strictly speaking O(1), but the complexity requirements for
>iterators don't make much sense anyway.
>
>MS STL returns the cached path by reference so it can't be a
>bidirectional iterator, and pretending to be one would definitely not be
>harmless (think about reverse_iterator<path_iterator>).
>
>--
>Std-Proposals mailing list
>Std-Proposals_at_[hidden]
>https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
Sorry for missing your email for not being cc'ed. You're right! I didn't notice such problem and it seems to be already discussed by author of ranges (Validity of references obtained from out-of-lifetime iterators · Issue #156 · ericniebler/stl2). This is a more profound problem that I previously expected.
Again, sorry and much thanks!
Liang Jiaming
From: Ell via Std-Proposals <std-proposals_at_[hidden]>
Date: 2026-02-04 06:40:12
To: std-proposals_at_[hidden]
cc: Ell
Title: Re: [std-proposals] filesystem::path::iterator should be bidirectional_iterator even if it's not Cpp17BidirectionalIterator>On Tuesday, February 3rd, 2026 at 11:18 PM, Arthur O'Dwyer via Std-Proposals <std-proposals_at_[hidden]> wrote:
>
>> On Thu, Jan 29, 2026 at 8:48 PM 梁家铭 via Std-Proposals <std-proposals_at_[hidden]> wrote:
>>
>> > Hi,
>> >
>> > Recently I find that `filesystem::path::iterator` is not bidirectional iterator, as specified in Issue 2674: Bidirectional iterator requirement on path::iterator is very expensive. It fulfills all requirements of Cpp17BidirectionalIterator except that there is no requirement that two equal iterators be bound to the same object (See [fs.class.path]). The reason is that it allows the iterator to cache filename component (as libc++ and MS-STL do) instead of storing a container of components in filesystem::path (as libstdc++ does, unfortunately). However, it also degrades path::iterator from Cpp17BidirectionalIterator to Cpp17InputIterator (well only libstdc++ can and indeed mark it with bidirectional_iterator_tag). Such degradation is also counter-intuitive and makes many components in `<algorithm>` inapplicable (e.g. libc++ issue: https://github.com/llvm/llvm-project/issues/55683).
>> >
>> > However, such simplification is very like `std::views::split`, which makes it fulfill bidirectional_iterator since C++20 if we examine all concepts one by one except the iterator tag. And C++20 allows us to define `iterator_concept` instead of examining `iterator_tag`. So I think we should make a fix DR (bold means wording change):
>> >
>> > A path::iterator is a constant iterator meeting all the requirements of a Cpp17BidirectionalIterator except that, for dereferenceable iterators a and b of type path::iterator with a == b, there is no requirement that *a and *b are bound to the same object.
>> > Its value_type is path. Therefore, it should fulfill concept
>> > bidirectional_iterator.
>> >
>> > And implementations can utilize `iterator_concept` to support it.
>>
>>
>> This sounds to me like a reasonable topic for a paper. I mean, this seems 100% like LEWG design territory — although I admit I'm confused by the existence of LWG 2674 and the implementation divergence between libc++/libstdc++ and Microsoft.
>>
>> I haven't investigated this area myself, so I don't have a concrete suggestion for wording. But the stuff you wrote in green above is not good wording. Don't say something "should" do something; just show the actual diff you're proposing. Find the words in the Standard that are currently as-they-should-not-be, and show how to replace them with something better.
>> You say path::iterator should [sic] "fulfill" concept `bidirectional_iterator`. But that's not a thing. We can say that path::iterator satisfies `bidirectional_iterator`; this is already true on libc++ and libstdc++, but false on MS STL. However, I'm confused by your phrasing — are you saying you want path::iterator to satisfy `bidirectional_iterator` without modeling `bidirectional_iterator`? Doesn't that make lots of usages IFNDR, technically? Obviously such IFNDR-ness would be harmless in practice; but how could WG21 possibly standardize anything along those lines with a straight face — "we provide a library type that satisfies a library concept but doesn't model it"? That way lies madness, it seems to me.
>> Maybe I'm just missing something basic; again, I haven't looked deeply at this at all. But you could help by providing the exact wording you think ought to change, and how to change it.
>>
>
>
>C++20 forward iterators still require returned lvalues to outlive the
>iterator
>(https://eel.is/c++draft/iterator.concepts#iterator.concept.forward-3),
>so they can't both cache the result and return it by reference. libc++
>returns the cached path by value, so it can and does declare
>iterator_concept as bidirectional. Not sure when it was added, OP might
>want to try a newer version. I'm also not sure if dereferencing the
>iterator is strictly speaking O(1), but the complexity requirements for
>iterators don't make much sense anyway.
>
>MS STL returns the cached path by reference so it can't be a
>bidirectional iterator, and pretending to be one would definitely not be
>harmless (think about reverse_iterator<path_iterator>).
>
>--
>Std-Proposals mailing list
>Std-Proposals_at_[hidden]
>https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
Received on 2026-02-09 06:24:23
