2

Looking at this cppreference.com page for std::filesystem::path::filename, the method's description is literaly just "equivalent to relative_path().empty() ? path() : *--end()". I've never seen that syntax "*--end()". I can figure out what it does from the context, but what does it mean exactly? And could it be used in a different context to extract, say, a substring?

Matheus Leão
  • 417
  • 4
  • 12
  • 2
    `end()` returns an iterator that is is one past the last element. `--` makes the iterator point to the one before it, the last element. `*` gets the element referred to by the iterator. – user4581301 Oct 17 '19 at 23:55
  • 1
    Essentially, it would mean same as `back()` if `path` had that member like containers do. – eerorika Oct 18 '19 at 00:12

1 Answers1

2

First, let's look at std::filesystem::path::begin()/end(). This allows you to iterate through a path one directory at a time, so for /user/kenyn/foo.bar with this code:

fs::path p = "/user/kenyn/foo.bar";
for(auto &e : p)
    std::cout << e << '\n';

We would see:

user
kenyn
foo.bar

So, what is *(--(p.end()))? I've added extra brackets so we can see we get an iterator pointing to one past the last element with p.end(), move back one with the -- to get a reference to foo.bar, then dereference the iterator with * to give us a pointer to the final path element "foo.bar".

The complete expression, then:

relative_path().empty() ? path() : *--end()

Says if there is no relative path (ie, just a file name or nothing at all), return the whole thing, else if there is a relative path, return the last element of the list of paths, which will be the file name.

Ken Y-N
  • 14,644
  • 21
  • 71
  • 114