【发布时间】:2018-02-18 14:48:36
【问题描述】:
考虑以下关于路径分解的断言,其中每个局部变量,例如stem 具有明显的初始化,例如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);
这一切都有效,除了最后一行——因为fs::path 没有定义operator+。它有operator+=,但没有operator+。
这里有什么故事?
我已经确定我可以通过添加我自己的operator+ 来编译这段代码。有什么理由不这样做吗? (请注意,这是在我自己的命名空间中;我不会重新打开 namespace std。)
fs::path operator+(fs::path a, const fs::path& b)
{
a += b;
return a;
}
我对这个问题的唯一假设是:
也许设计者担心
operator+太容易与std::string的operator+混淆。但这似乎很愚蠢,因为它在语义上做了完全相同的事情(那么为什么要关心它是否被混为一谈呢?)。而且,当设计path.append("x")与str.append("x")和path.concat("x")在语义上不同 以在语义上相同时,设计师似乎并不关心新手的困惑 作为str.append("x")。也许
path的隐式转换operator string_type() const会导致某些p + q变得模棱两可。但我一直想不出这样的案例。
【问题讨论】:
-
来自上述链接的基本原理:“basic_string operator+ 要求的 12 个重载把我吓跑了,我再也没有回到这个问题上。” 呵呵。像
<filesystem>这么庞大,我真的没想到“嗯,懒惰”会是最终的答案! :P -
这不完全是懒惰,而是在考虑重载数量时害怕。我们已经抱怨说,当我们现在有
string_view时,12 个string重载是不够的 - 没有string+string_view。这里会有很多很多。一旦你有path+path有人会要求path+string(在Windows上是path+wstring),path+string_view,path+ @987654 ,path+char。然后当然是string+path等,将数字翻倍。以及整个批次的左值和右值版本。 -
请注意,已经有a conflict between operator<< for string and path 让每个人都感到惊讶。现在添加几十个新的运营商可能不是最好的主意。
-
conflict with operator<< 是由两种最糟糕的实践组合产生的:隐式转换(来自整个世界,不少于!)和重载
operator<<以做一些意想不到的事情(即,它打印@ 987654364@ 而不是path.string())。我对任何一个糟糕的决定都零同情。
标签: c++ c++17 boost-filesystem