On Mon, Aug 26, 2019 at 6:21 AM Niall Douglas via Lib-Ext <lib-ext@lists.isocpp.org> wrote:
On 26/08/2019 02:14, Arthur O'Dwyer wrote:
> A single path is not conceptually a "range" of /*anything*/ — it's just
> a single filesystem path.

filesystem::path defines that it is a range of filesystem path
components. Apart from the native path separator being a valid character
in a path component on some systems, I find that a reasonable design choice.

Well, that;
and that you lose the separators between components;
and that you can't tell the difference between a drive letter and a path component;
and that your sample code tries to "std::cout <<" paths, which doesn't work because every `path` object is implicitly wrapped in `std::quoted`.

A path itself is not a range of anything — it's just a path.
std::filesystem::path breaks this intuition by giving std::filesystem::path ".begin()" and ".end()" methods, which causes C++ to treat it like a range type. But that's just an example of "lying to the compiler." Giving .begin() and .end() methods to a C++ class type that does not itself represent a range of elements was the original sin.

> What it should have done was to give `std::filesystem::path` one or more
> "range accessor" methods:
>     for (auto&& component : mypath.components()) { ... }
>     for (auto&& character : mypath.str()) { ... }

Or iteration returns a path_component type, as Victor suggested.

Unfortunately, that won't fix any of the bugs in your original code sample. You'll still lose the separators between components, and the drive letter, and emit many spurious quotation marks. To fix your original code sample, you need some way to tell your generic code that a std::filesystem::path should never be treated as a range.

However, your original code sample is broken anyway for things like `std::vector<int>` — it prints {1,2} and {12} identically.

Disabling path component iteration I don't think is worth the pain, personally.

I don't see any pain except the pain of people trying to use `for (auto&& elt : path)` in production. Stopping that erroneous construct from compiling would be a good thing.