来自 std::filesystem::u8path(const char8_t*) 的 VS 错误

问题描述

在这个简单的 C++20 程序中

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

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

我在 stdcpplatest 模式下从 Visual Studio 2019 16.10.0 收到错误

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>        ]

除了在 c++20 中弃用 u8path 函数外,我在这里没有发现任何问题,并且代码在 gcc 11 和 clang 12 中使用选项 -std=c++20 -Wall 编译得很好,没有任何警告.请帮忙找出这里有什么问题。

解决方法

u8path 接受 char8_t 的能力是 C++20 标准中相对较晚的补充。有问题的错误引用了 N4810,这是一个包含 char8_t(以及 filesystem::path 构造函数的重载)的草稿,但草稿是之前 { {1}} 已更改为采用 u8path 字符串。

所以 VS 根本没有实现 current version of that part of the standard

,

当 C++20 采用 P0482 (char8_t: A type for UTF-8 characters and strings) 时,它无意中导致 std::filesystem::u8path() 不再接受 u8 前缀字符串文字(或一般基于 char8_t 的字符串) .这是作者(我)的疏忽,已通过 P1423 (char8_t backward compatibility remediation) 更正(对于 C++20)。 Microsoft claims 在 VS 2019 16.6 (19.26) 中实现了 P1423,但至少该提案的这一部分似乎并非如此。 Testing on godbolt.org 表明 VS 2019 16.2 (19.22) 到 VS 2019 16.8 (19.28) 和最新预览版本在使用 {{1 编译时都拒绝对带有 std::filesystem::u8path() 前缀字符串文字的 u8 调用}}(gcc、clang 和 icc 都在其 C++20 一致性模式下接受测试)。

Github 用户 fsb4000 向 Microsoft STL 维护者发送了 already reported this issue(显然是为了响应此 stackoverflow 帖子)。