在 gcc7.3(使用 C++14)和 gcc9.3(使用 C++17)中运行这段代码时,我看到不同的输出:
#include <iostream>
#if (__cplusplus >= 201703L)
#include <filesystem>
namespace fs = std::filesystem;
#else
#include <experimental/filesystem>
namespace fs = std::experimental::filesystem;
#endif
using namespace std;
std::string getBaseName(const std::string& filePath) {
return fs::path(filePath).filename().string();
}
int main()
{
std::cout<<"getBaseName(/test/absolute/dir/)="<<getBaseName("/test/absolute/dir/")<<std::endl;
std::cout<<"getBaseName(/)="<<getBaseName("/")<<std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在 gcc7.3 (C++14) 中,它给了我:
getBaseName(/test/absolute/dir/)=.
getBaseName(/)=/
Run Code Online (Sandbox Code Playgroud)
在 gcc9.3(C++17) 中,我得到:
getBaseName(/test/absolute/dir/)=
getBaseName(/)=
Run Code Online (Sandbox Code Playgroud)
我想知道这是否是 gcc7.3 中的错误(因此是 std::experimental),如果是,我们是否有任何不依赖任何第三方库的解决方法?
<experimental/filesystem>根据Filesystem TS(基本上是C++14的实验性扩展)实现文件系统库,而<filesystem>C++17(及更高版本)的文件系统库部分。
两者不是相同的规格。后者基于前者的经验,但由于前者从来不是标准本身的一部分,因此可以针对 C++17 对 API 进行更改。
这是这些变化之一。具体来说,变化是对C++17草案的NB评论的解决。请参阅https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0492r2.html#US74。
对于解决方法,确实没有。<experimental/filesystem>根本不需要 C++ 编译器来支持,并且<filesystem>仅从 C++17 开始可用。
如果您确实需要 C++14 或更早版本的支持,也许您应该使用它<boost/filesystem>来实现可移植性。但是,我认为该接口可能与 C++17std::filesystem和文件系统 TS 略有不同。
否则,我建议只需要 C++17 并放弃对<experimental/filesystem>.