17

Consider the following assertions about path decomposition, where each local variable e.g. stem has the obvious initialization e.g. auto stem = path.stem()

assert(root_path == root_name / root_directory);
assert(path == root_name / root_directory / relative_path);
assert(path == root_path / relative_path);

assert(path == parent_path / filename);
assert(filename == stem + extension);

This all works, except for the last line — because fs::path does not define an operator+. It has operator+=, but no operator+.

What's the story here?


I've determined that I can make this code compile by adding my own operator+. Is there any reason not to do this? (Notice this is in my own namespace; I'm not reopening namespace std.)

fs::path operator+(fs::path a, const fs::path& b)
{
    a += b;
    return a;
}

My only hypotheses on the subject are:

  • Maybe the designers worried that operator+ would be too easily confused with std::string's operator+. But that seems silly, since it does exactly the same thing semantically (so why care if it gets conflated?). And it also seems that the designers didn't care about newbies' confusion when they designed path.append("x") to do something semantically different from str.append("x") and path.concat("x") to do something semantically the same as str.append("x").

  • Maybe path's implicit conversion operator string_type() const would cause some variety of p + q to become ambiguous. But I've been unable to come up with any such case.

cpplearner
  • 10,463
  • 2
  • 34
  • 57
Quuxplusone
  • 19,419
  • 5
  • 72
  • 137
  • 5
    https://timsong-cpp.github.io/lwg-issues/2668 – T.C. Sep 10 '17 at 05:45
  • 1
    Rationale from the above link: *"The 12 overloads required by basic_string operator+ scared me off, and I never came back to the issue."* Huh. For as ginormous as `` is, I really didn't expect "meh, laziness" was going to be the ultimate answer! :P – Quuxplusone Sep 10 '17 at 06:28
  • 5
    It's not exactly laziness, but being *scared* when considering the number of overloads. And we already have complaints that the 12 `string` overloads are not enough when we now have `string_view` - there is no `string` + `string_view`. Here it would be many, many more. Once you have `path` + `path` someone will ask for `path` + `string` (which is `path`+ `wstring` on Windows), `path` + `string_view`, `path` + `const char*`, `path` + `char`. And then of course `string`+ `path`, etc to double the number. And the lvalue and rvalue versions of the whole lot. – Bo Persson Sep 10 '17 at 09:52
  • 1
    Note that there already is [a conflict between operator<< for string and path](http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#2989) which surprised everyone. Now adding a couple of dozen new operators might not be the best idea. – Bo Persson Sep 10 '17 at 09:56
  • 1
    The [conflict with operator< – Quuxplusone Sep 10 '17 at 19:53
  • Proposed resolution from the link above: `Future changes to the language, such as concepts, and changes to the library, such as basic_string_view, may allow reduction of the complexity of the class path interface. The LWG may wish to reconsider this issue at that time.` – Roi Danton Mar 12 '19 at 10:13
  • Note that your wrong-namespace overload will not be found by (dependent) ADL. – Davis Herring Jul 29 '20 at 02:57

1 Answers1

4

This was entered as a defect against the filesystem library, and because of the interface complexity and the ability to work around by converting to strings and back to paths, it was judged to not be a defect. Read all about it here: https://timsong-cpp.github.io/lwg-issues/2668

CHKingsley
  • 186
  • 9
  • This is more appropriate as a comment. Consider commenting when you have the rep. – Tom Aranda Nov 30 '17 at 03:49
  • 6
    @TomAranda Sounds like an answer to me. – Raymond Chen Nov 30 '17 at 05:18
  • 3
    Wow, this is really annoying. Isn't filesystem::path designed to make path concatenation simple and readable? The simple situation outputDirPath / fileBasePath + ".extension" requires casting. So ugly. Who cares about 12 more operators defined in a huge library? I use the library to make my code simpler. Otherwise I can concatenate strings in the first place. – Alexander Jul 29 '19 at 22:11