g ++打破std :: filesystem :: last_write_time中的更改

时间:2019-06-21 17:48:25

标签: c++ g++ c++17

在最近的操作系统升级中,我注意到我的代码中的一小部分停止了编译-看来原因是从g++-8切换到g++-9

此代码可以在g++ 8.3.0上正常编译(已使用Dockerhub的gcc:8.3映像对此进行了验证)

#include <filesystem>
#include <chrono>

int main() {
    namespace fs = std::filesystem;
    using namespace std::chrono_literals;
    std::filesystem::last_write_time("test", std::chrono::system_clock::now() - 5min);
}

g++ 9.1.0上,失败并显示:

test.cpp: In function 'int main()':
test.cpp:8:69: error: no matching function for call to 'last_write_time(const char [5], std::chrono::time_point<std::chrono::_V2::system_clock, std::chrono::duration<long int, std::ratio<1, 1000000000> > >)'
    8 |  fs::last_write_time("test", std::chrono::system_clock::now() - 5min);
      |                                                                     ^
In file included from /usr/local/include/c++/9.1.0/filesystem:39,
                 from test.cpp:1:
/usr/local/include/c++/9.1.0/bits/fs_ops.h:243:19: note: candidate: 'std::filesystem::file_time_type std::filesystem::last_write_time(const std::filesystem::__cxx11::path&)'
  243 |   file_time_type  last_write_time(const path& __p);
      |                   ^~~~~~~~~~~~~~~
/usr/local/include/c++/9.1.0/bits/fs_ops.h:243:19: note:   candidate expects 1 argument, 2 provided
/usr/local/include/c++/9.1.0/bits/fs_ops.h:244:19: note: candidate: 'std::filesystem::file_time_type std::filesystem::last_write_time(const std::filesystem::__cxx11::path&, std::error_code&)'
  244 |   file_time_type  last_write_time(const path& __p, error_code& __ec) noexcept;
      |                   ^~~~~~~~~~~~~~~
In file included from /usr/local/include/c++/9.1.0/filesystem:36,
                 from test.cpp:1:
/usr/local/include/c++/9.1.0/bits/fs_fwd.h:362:47: note:   no known conversion for argument 2 from 'std::chrono::time_point<std::chrono::_V2::system_clock, std::chrono::duration<long int, std::ratio<1, 1000000000> > >' to 'std::error_code&'
  362 |   file_time_type last_write_time(const path&, error_code&) noexcept;
      |                                               ^~~~~~~~~~~
In file included from /usr/local/include/c++/9.1.0/filesystem:39,
                 from test.cpp:1:
/usr/local/include/c++/9.1.0/bits/fs_ops.h:245:8: note: candidate: 'void std::filesystem::last_write_time(const std::filesystem::__cxx11::path&, std::filesystem::file_time_type)'
  245 |   void last_write_time(const path& __p, file_time_type __new_time);
      |        ^~~~~~~~~~~~~~~
/usr/local/include/c++/9.1.0/bits/fs_ops.h:245:56: note:   no known conversion for argument 2 from 'time_point<std::chrono::_V2::system_clock,[...]>' to 'time_point<std::filesystem::__file_clock,[...]>'
  245 |   void last_write_time(const path& __p, file_time_type __new_time);
      |                                         ~~~~~~~~~~~~~~~^~~~~~~~~~
/usr/local/include/c++/9.1.0/bits/fs_ops.h:246:8: note: candidate: 'void std::filesystem::last_write_time(const std::filesystem::__cxx11::path&, std::filesystem::file_time_type, std::error_code&)'
  246 |   void last_write_time(const path& __p, file_time_type __new_time,
      |        ^~~~~~~~~~~~~~~
/usr/local/include/c++/9.1.0/bits/fs_ops.h:246:8: note:   candidate expects 3 arguments, 2 provided

shell returned 1

Press ENTER or type command to continue

编译命令:g++ -std=c++17 test.cpp -lstdc++-fs(尽管自stdc++-fs起就不需要链接g++9

我的问题是-按照我的意图,此功能的惯用用法是什么?即将文件的上次写入时间更改为五分钟前。

我知道,如果引入了重大更改,我会以某种非惯用的方式使用它。

2 个答案:

答案 0 :(得分:7)

正如@LightnessRacesinOrbit在其答案中指出的那样,splice所使用的std::filesystem::file_time_type使用了未指定的roleId:0类型。这意味着,从一个编译器转移到同一编译器的另一个甚至版本时,完全合法。

但是,您可以做的是获取实现所使用的时钟,并自己使用它。 std::chrono::time_point的创建采用了将其创建为模板参数的时钟类型,并且它公开了表示该时钟类型的公共 HTML <div style="text-align:center"> <p>Hello World!</p> <figure id="mapa"> <img src="mapa.png" width="500" height="500" usemap="#map"/> <svg width="500" height="500"> <line x1="10" y1="100" x2="60" y2="100" stroke="red"/> <line x1="60" y1="100" x2="200" y2="300" stroke="red"/> <line x1="200" y1="300" x2="400" y2="400" stroke="red"/> </svg> </figure> </div> CSS <style> figure{ position:relative; } img{ position:absolute; } svg{ position:absolute; } </style> 。因此,为了方便地获取时钟并调用last_write_time,您可以使用

time_point

答案 1 :(得分:3)

cppreference.com's example对此进行了修饰。

您将std::chrono::time_point<std::chrono::system_clock>赋予std::file_time_type从未移植过;它恰好在您以前的工具链上起作用。那真的不是你的错:您不可避免地依赖于实现细节。

C ++ 20引入了可移植的替代方案,因此您可以这样做:

std::filesystem::last_write_time("test", std::chrono::file_clock::now() - 5min);
//                                                    ^^^^^^^^^^

…即使用file_clock,而不仅仅是希望替代方法可以转换为工具链使用的任何实现定义的时钟。

尽管it doesn't look like it,我不能肯定地说GCC 9是否支持。如果有解决方法,我不知道有什么解决方法(这就是为什么进行C ++ 20更改的原因)。

This problem affects other people on other toolchains