https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95642
Bug ID: 95642 Summary: std::fstream ctr and open member functions fail to compile with argument of custom type convertible to std::filesystem::path Product: gcc Version: 10.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: manx-bugzilla at problemloesungsmaschine dot de Target Milestone: --- Created attachment 48719 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=48719&action=edit test case std::fstream (and related classes) ctr and open member functions fail to compile with an argument of a custom type implicitly convertible to std::filesystem::path. When compiling the attached test.cpp (via 'g++ -std=c++17 -Wall -Wextra -O3 -c test.cpp'), gcc (Ubuntu 9.3.0-10ubuntu2) 9.3.0 fails with the error message [1]. This does also happen with GCC 8 and 10, as well as trunk (as of today on godbolt.org). C++17 [fstream] does not list any SFINAE in the std::filesystem::path overload that I am trying to call here, thus I think this is a GCC/libstdc++ bug. Note that Clang/LLVM (with libc++) as well as MSVC correctly compile the provided test case. See https://godbolt.org/z/K6v3Cb . [1]: test.cpp: In function ‘void foo(mypath)’: test.cpp:7:41: error: no matching function for call to ‘std::basic_fstream<char>::basic_fstream(mypath&, const openmode&)’ 7 | std::fstream bar(p, std::ios::binary); | ^ In file included from test.cpp:2: /usr/include/c++/9/fstream:1106:7: note: candidate: ‘std::basic_fstream<_CharT, _Traits>::basic_fstream(std::basic_fstream<_CharT, _Traits>&&) [with _CharT = char; _Traits = std::char_traits<char>]’ 1106 | basic_fstream(basic_fstream&& __rhs) | ^~~~~~~~~~~~~ /usr/include/c++/9/fstream:1106:7: note: candidate expects 1 argument, 2 provided /usr/include/c++/9/fstream:1098:2: note: candidate: ‘template<class _Path, class _Require> std::basic_fstream<_CharT, _Traits>::basic_fstream(const _Path&, std::ios_base::openmode)’ 1098 | basic_fstream(const _Path& __s, | ^~~~~~~~~~~~~ /usr/include/c++/9/fstream:1098:2: note: template argument deduction/substitution failed: /usr/include/c++/9/fstream:1097:32: error: ‘struct mypath’ has no member named ‘make_preferred’ 1097 | template<typename _Path, typename _Require = _If_fs_path<_Path>> | ^~~~~~~~ /usr/include/c++/9/fstream:1083:7: note: candidate: ‘std::basic_fstream<_CharT, _Traits>::basic_fstream(const string&, std::ios_base::openmode) [with _CharT = char; _Traits = std::char_traits<char>; std::string = std::__cxx11::basic_string<char>; std::ios_base::openmode = std::_Ios_Openmode]’ 1083 | basic_fstream(const std::string& __s, | ^~~~~~~~~~~~~ /usr/include/c++/9/fstream:1083:40: note: no known conversion for argument 1 from ‘mypath’ to ‘const string&’ {aka ‘const std::__cxx11::basic_string<char>&’} 1083 | basic_fstream(const std::string& __s, | ~~~~~~~~~~~~~~~~~~~^~~ /usr/include/c++/9/fstream:1053:7: note: candidate: ‘std::basic_fstream<_CharT, _Traits>::basic_fstream(const char*, std::ios_base::openmode) [with _CharT = char; _Traits = std::char_traits<char>; std::ios_base::openmode = std::_Ios_Openmode]’ 1053 | basic_fstream(const char* __s, | ^~~~~~~~~~~~~ /usr/include/c++/9/fstream:1053:33: note: no known conversion for argument 1 from ‘mypath’ to ‘const char*’ 1053 | basic_fstream(const char* __s, | ~~~~~~~~~~~~^~~ /usr/include/c++/9/fstream:1043:7: note: candidate: ‘std::basic_fstream<_CharT, _Traits>::basic_fstream() [with _CharT = char; _Traits = std::char_traits<char>]’ 1043 | basic_fstream() | ^~~~~~~~~~~~~ /usr/include/c++/9/fstream:1043:7: note: candidate expects 0 arguments, 2 provided test.cpp:8:33: error: no matching function for call to ‘std::basic_fstream<char>::open(mypath&, const openmode&)’ 8 | bar.open(p, std::ios::binary); | ^ In file included from test.cpp:2: /usr/include/c++/9/fstream:1177:7: note: candidate: ‘void std::basic_fstream<_CharT, _Traits>::open(const char*, std::ios_base::openmode) [with _CharT = char; _Traits = std::char_traits<char>; std::ios_base::openmode = std::_Ios_Openmode]’ 1177 | open(const char* __s, | ^~~~ /usr/include/c++/9/fstream:1177:24: note: no known conversion for argument 1 from ‘mypath’ to ‘const char*’ 1177 | open(const char* __s, | ~~~~~~~~~~~~^~~ /usr/include/c++/9/fstream:1218:7: note: candidate: ‘void std::basic_fstream<_CharT, _Traits>::open(const string&, std::ios_base::openmode) [with _CharT = char; _Traits = std::char_traits<char>; std::string = std::__cxx11::basic_string<char>; std::ios_base::openmode = std::_Ios_Openmode]’ 1218 | open(const std::string& __s, | ^~~~ /usr/include/c++/9/fstream:1218:31: note: no known conversion for argument 1 from ‘mypath’ to ‘const string&’ {aka ‘const std::__cxx11::basic_string<char>&’} 1218 | open(const std::string& __s, | ~~~~~~~~~~~~~~~~~~~^~~ /usr/include/c++/9/fstream:1240:2: note: candidate: ‘template<class _Path> std::_If_fs_path<_Path, void> std::basic_fstream<_CharT, _Traits>::open(const _Path&, std::ios_base::openmode) [with _Path = _Path; _CharT = char; _Traits = std::char_traits<char>]’ 1240 | open(const _Path& __s, | ^~~~ /usr/include/c++/9/fstream:1240:2: note: template argument deduction/substitution failed: /usr/include/c++/9/fstream: In substitution of ‘template<class _Path> std::_If_fs_path<_Path, void, decltype (declval<_Path&>().make_preferred().filename())> std::basic_fstream<char>::open<_Path>(const _Path&, std::ios_base::openmode) [with _Path = mypath]’: test.cpp:8:33: required from here /usr/include/c++/9/fstream:1240:2: error: ‘struct mypath’ has no member named ‘make_preferred’