1

In this simple C++20 program

#define _SILENCE_CXX20_U8PATH_DEPRECATION_WARNING //suppress VS warning
#include <filesystem>

int main()
{
    auto p = std::filesystem::u8path(u8"a");
}

I get the error from Visual Studio 2019 16.10.0 in stdcpplatest mode:

1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30037\include\filesystem(279,13): error C2338: invalid value_type, see N4810 D.17 [depr.fs.path.factory]/1
1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30037\include\filesystem(346): message : see reference to function template instantiation 'std::wstring std::filesystem::_Convert_stringoid_to_wide<_Conversion>(const std::basic_string_view<char8_t,std::char_traits<char8_t>>,_Conversion)' being compiled
1>        with
1>        [
1>            _Conversion=std::filesystem::_Utf8_conversion
1>        ]
1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30037\include\filesystem(1442): message : see reference to function template instantiation 'std::wstring std::filesystem::_Convert_Source_to_wide<char8_t[2],std::filesystem::_Utf8_conversion>(const _Src (&),_Conversion)' being compiled
1>        with
1>        [
1>            _Src=char8_t [2],
1>            _Conversion=std::filesystem::_Utf8_conversion
1>        ]
1>test.cpp(298): message : see reference to function template instantiation 'std::filesystem::path std::filesystem::u8path<char8_t[2],0>(const _Src (&))' being compiled
1>        with
1>        [
1>            _Src=char8_t [2]
1>        ]

Except of deprecation of u8path function in c++20, I do not see anything wrong here, and the code compiles fine in gcc 11 and clang 12 with the options -std=c++20 -Wall, without any warnings. Please help to find what is wrong here.

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
Fedor
  • 17,146
  • 13
  • 40
  • 131

2 Answers2

3

The ability for u8path to take char8_t was a relatively late addition to the C++20 standard. The error in question cites N4810, which was a draft that contains char8_t (as well as overloads for filesystem::path constructors), but the draft was written before u8path was changed to take char8_t strings.

So VS simply has not implemented the current version of that part of the standard.

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
2

When P0482 (char8_t: A type for UTF-8 characters and strings) was adopted for C++20, it unintentionally resulted in std::filesystem::u8path() no longer accepting u8 prefixed string literals (or char8_t-based strings in general). This was an oversight by the author (me) that was corrected (for C++20) via P1423 (char8_t backward compatibility remediation). Microsoft claims to have implemented P1423 in VS 2019 16.6 (19.26), but it seems not so for at least this part of that proposal. Testing on godbolt.org demonstrates that VS 2019 16.2 (19.22) through VS 2019 16.8 (19.28) and the latest preview release all reject calls to std::filesystem::u8path() with a u8 prefixed string literal when compiled with /std:c++latest (gcc, clang, and icc all accept the test in their C++20 conformance modes).

Github user fsb4000 has already reported this issue to the Microsoft STL maintainers (apparently in response to this stackoverflow post).

Tom Honermann
  • 1,774
  • 1
  • 7
  • 10