c++ - gcc7.3 和 gcc9.3 之间 filesystem::path(filePath).filename() 的不同行为

标签 c++ c++17 c++14

在 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;
}

在 gcc7.3 (C++14) 中,它给了我:

getBaseName(/test/absolute/dir/)=.
getBaseName(/)=/

在 gcc9.3(C++17) 中,我得到:

getBaseName(/test/absolute/dir/)=
getBaseName(/)=

我想知道这是否是 gcc7.3(因此是 std::experimental)中的错误,如果是,我们是否有任何不依赖任何第三方库的解决方法?

最佳答案

<experimental/filesystem>根据文件系统 TS(基本上是 C++14 的实验性扩展)实现文件系统库,同时 <filesystem>是 C++17(及更高版本)的文件系统库部分。

两者不是相同的规范。后者基于前者的经验,但由于前者从来都不是标准本身的一部分,因此可以针对 C++17 对 API 进行更改。

这是这些变化之一。具体来说,变化是NB评论对C++17草案的决议。参见 https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0492r2.html#US74 .


对于解决方法,确实没有。不需要 C++ 编译器来支持 <experimental/filesystem>完全和<filesystem>仅从 C++17 开始可用。

如果你真的需要对 C++14 或更早版本的支持,也许你应该使用 <boost/filesystem> 而不是为了便携性。但是,我认为接口(interface)可能与 C++17 std::filesystem 略有不同。和文件系统 TS。

否则我建议只需要 C++17 并放弃对 <experimental/filesystem> 的任何支持.

关于c++ - gcc7.3 和 gcc9.3 之间 filesystem::path(filePath).filename() 的不同行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72857889/

相关文章:

c++ - 结构的指针以及如何访问元素

c++ - 对数时间聚合的数量

c++ - 在 Win32 API 中禁用组合框项

C++ 异步 + future (延迟 vs 异步)

c++ - 当我将对象推送到 std::vector push_back 时,std::move 会破坏我的对象

c++ - C++ 17 中 Clang 的不明确部分特化

c++ - 在 C++ 中内联私有(private)方法

c++ - 如何将可变参数模板参数的特征值减少为一个值?

c++ - 使用 std::Optional 而不是自己的结构

c++ - 为什么我无法创建唯一指针