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’