On Tue, Aug 27, 2019 at 7:53 AM Niall Douglas via Lib-Ext <lib-ext@lists.isocpp.org> wrote:
On 26/08/2019 22:32, David Stone wrote:
> I have several times written (and seen written) code like
>
>     auto directory = std::filesystem::path(...);
>     for (auto const & path : directory) {
>         use(path);
>     }
>
> when what I meant was
>
>     auto directory = std::filesystem::path(...);
>     for (auto path_it = std::filesystem::directory_iterator(directory);
> path_it != std::filesystem::directory_iterator(); ++path_it) {
>         use(*path_it);
>     }

I'd have some sympathy for you if you had written:

     auto directory = std::filesystem::path(...);
     for (auto const & path : *directory) {
         use(path);
     }

... and you did not get directory enumeration, as it would be reasonable
to expect dereferencing a path might do something like contents enumeration.

But if you iterate a container of X, you expect to yield X.

Well, I can see the logic for someone naively assuming that "/usr/local" would be a 'container' holding "/usr/local/include", "/usr/local/bin", "/usr/local/lib", and so on. That's very roughly what happens at the filesystem level when you do an `ls`.  It wouldn't be very "C++-ish" to design the actual class type that way, but a naive user by definition doesn't know that.

A user who has worked in C++ for a while, and knows that C++ treats paths essentially as strings, might naively assume that "/usr/local" was a string-style 'container' holding '/', 'u', 's', 'r', '/', 'l', 'o', 'c', 'a', and 'l'.  (They might even verify that `path::value_type` is a character type. It is.)  As you say, for historical reasons that's not what the Committee gave us; but a user who merely uses C++ by definition doesn't know committee political history.

Any user is surprised (the first time) when "/usr/local" turns out to be a 'container' holding the meaningless fragments "/", "usr", and "local".

–Arthur