带有 {fmt} 库和 Visual Studio 2022 (17.2.2) 的用户定义类型
User-defined types with {fmt} library and Visual Studio 2022 (17.2.2)
我正在使用https://github.com/fmtlib/fmt (commit hash 7e4ad40171aa552d38cb99a5c181a0d7b150facc - at the time of this writing pretty new) with the newest Visual Studio 2022
version (17.2.2) and following this tutorial here
我想让这个工作:
struct complex
{
double a;
double b;
};
template<>
struct fmt::formatter<complex>
{
template<typename ParseContext>
constexpr auto parse(ParseContext& ctx) { return ctx.begin(); }
template<typename FormatContext>
auto format(complex const& number, FormatContext& ctx) {
return format_to(ctx.out(), "{0} +i{1}", number.a, number.b);
}
};
// ...
// somewhere in main
complex number{1, 2};
std::string message = fmt::format("The number is {}.\n", number);
我收到错误消息:
ERROR: G:/dev/piper/devertexwahn/flatland/tests/third_party/BUILD.bazel:42:8: Compiling flatland/tests/third_party/fmt_test.cpp failed: (Exit 2): cl.exe failed: error executing command C:\Program Files\Microsoft Visual Studio22\Community\VC\Tools\MSVC.32.31326\bin\HostX64\x64\cl.exe /nologo /DCOMPILER_MSVC /DNOMINMAX /D_WIN32_WINNT=0x0601 /D_CRT_SECURE_NO_DEPRECATE ... (remaining 44 arguments skipped)
flatland/tests/third_party/fmt_test.cpp(53): error C2668: 'std::format_to': ambiguous call to overloaded function
C:\Program Files\Microsoft Visual Studio22\Community\VC\Tools\MSVC.32.31326\include\format(3046): note: could be '_OutputIt std::format_to<OutputIt,const double&,const double&>(_OutputIt,const std::_Basic_format_string<char,const double &,const double &>,const double &,const double &)' [found using argument-dependent lookup]
with
[
_OutputIt=fmt::v8::appender,
OutputIt=fmt::v8::appender
]
G:\bazel_output_base\execroot\de_vertexwahn\bazel-out\x64_windows-fastbuild\bin\external\fmt\_virtual_includes\fmt\fmt/core.h(3195): note: or 'OutputIt fmt::v8::format_to<OutputIt,const double&,const double&,0>(OutputIt,fmt::v8::basic_format_string<char,const double &,const double &>,const double &,const double &)'
with
[
OutputIt=fmt::v8::appender
]
flatland/tests/third_party/fmt_test.cpp(52): note: while trying to match the argument list '(OutputIt, const char [10], const double, const double)'
with
[
OutputIt=fmt::v8::appender
]
G:\bazel_output_base\execroot\de_vertexwahn\bazel-out\x64_windows-fastbuild\bin\external\fmt\_virtual_includes\fmt\fmt/core.h(713): note: see reference to function template instantiation 'auto fmt::v8::formatter<complex,char,void>::format<Context>(const complex &,FormatContext &)' being compiled
with
[
Context=fmt::v8::format_context,
FormatContext=fmt::v8::format_context
]
G:\bazel_output_base\execroot\de_vertexwahn\bazel-out\x64_windows-fastbuild\bin\external\fmt\_virtual_includes\fmt\fmt/core.h(1457): note: see reference to function template instantiation 'bool fmt::v8::detail::has_const_formatter<U,Context>(void)' being compiled
with
[
U=complex,
Context=fmt::v8::format_context
]
G:\bazel_output_base\execroot\de_vertexwahn\bazel-out\x64_windows-fastbuild\bin\external\fmt\_virtual_includes\fmt\fmt/core.h(1486): note: see reference to class template instantiation 'fmt::v8::detail::arg_mapper<Context>::formattable<const complex &,complex>' being compiled
with
[
Context=fmt::v8::format_context
]
G:\bazel_output_base\execroot\de_vertexwahn\bazel-out\x64_windows-fastbuild\bin\external\fmt\_virtual_includes\fmt\fmt/core.h(1697): note: see reference to alias template instantiation 'fmt::v8::detail::mapped_type_constant<complex,Context>' being compiled
with
[
Context=fmt::v8::format_context
]
G:\bazel_output_base\execroot\de_vertexwahn\bazel-out\x64_windows-fastbuild\bin\external\fmt\_virtual_includes\fmt\fmt/core.h(1858): note: see reference to function template instantiation 'unsigned __int64 fmt::v8::detail::encode_types<Context,complex,>(void)' being compiled
with
[
Context=fmt::v8::format_context
]
G:\bazel_output_base\execroot\de_vertexwahn\bazel-out\x64_windows-fastbuild\bin\external\fmt\_virtual_includes\fmt\fmt/core.h(3167): note: see reference to class template instantiation 'fmt::v8::format_arg_store<fmt::v8::format_context,complex>' being compiled
flatland/tests/third_party/fmt_test.cpp(59): note: see reference to function template instantiation 'std::string fmt::v8::format<complex&>(fmt::v8::basic_format_string<char,complex &>,complex &)' being compiled
G:\bazel_output_base\execroot\de_vertexwahn\bazel-out\x64_windows-fastbuild\bin\external\fmt\_virtual_includes\fmt\fmt/core.h(1696): error C2062: type 'unknown-type' unexpected
G:\bazel_output_base\execroot\de_vertexwahn\bazel-out\x64_windows-fastbuild\bin\external\fmt\_virtual_includes\fmt\fmt/core.h(1696): error C2144: syntax error: 'unknown-type' should be preceded by '('
G:\bazel_output_base\execroot\de_vertexwahn\bazel-out\x64_windows-fastbuild\bin\external\fmt\_virtual_includes\fmt\fmt/core.h(1697): error C2039: 'value': is not a member of '`global namespace''
G:\bazel_output_base\execroot\de_vertexwahn\bazel-out\x64_windows-fastbuild\bin\external\fmt\_virtual_includes\fmt\fmt/core.h(1855): error C3615: constexpr function 'fmt::v8::detail::encode_types' cannot result in a constant expression
G:\bazel_output_base\execroot\de_vertexwahn\bazel-out\x64_windows-fastbuild\bin\external\fmt\_virtual_includes\fmt\fmt/core.h(1858): note: failure was caused by control reaching the end of a constexpr function
Target //flatland/tests/third_party:fmt_test failed to build
Use --verbose_failures to see the command lines of failed build steps.
该代码似乎适用于 Ubuntu 20.04 上的 GCC9 以及 macOS 上的 Apple CLang。知道我在这里做错了什么吗?
错误是由C++20引入的std::format_to
函数引起的。要修复它,请限定您对 fmt::format_to
的调用。例如,而不是
return format_to(ctx.out(), "{0} +i{1}", number.a, number.b);
改为这样做:
return fmt::format_to(ctx.out(), "{0} +i{1}", number.a, number.b);
有关详细信息,请参阅此问题:format conflict with Visual Studio 2022 17.2.0。
我正在使用https://github.com/fmtlib/fmt (commit hash 7e4ad40171aa552d38cb99a5c181a0d7b150facc - at the time of this writing pretty new) with the newest Visual Studio 2022
version (17.2.2) and following this tutorial here
我想让这个工作:
struct complex
{
double a;
double b;
};
template<>
struct fmt::formatter<complex>
{
template<typename ParseContext>
constexpr auto parse(ParseContext& ctx) { return ctx.begin(); }
template<typename FormatContext>
auto format(complex const& number, FormatContext& ctx) {
return format_to(ctx.out(), "{0} +i{1}", number.a, number.b);
}
};
// ...
// somewhere in main
complex number{1, 2};
std::string message = fmt::format("The number is {}.\n", number);
我收到错误消息:
ERROR: G:/dev/piper/devertexwahn/flatland/tests/third_party/BUILD.bazel:42:8: Compiling flatland/tests/third_party/fmt_test.cpp failed: (Exit 2): cl.exe failed: error executing command C:\Program Files\Microsoft Visual Studio22\Community\VC\Tools\MSVC.32.31326\bin\HostX64\x64\cl.exe /nologo /DCOMPILER_MSVC /DNOMINMAX /D_WIN32_WINNT=0x0601 /D_CRT_SECURE_NO_DEPRECATE ... (remaining 44 arguments skipped)
flatland/tests/third_party/fmt_test.cpp(53): error C2668: 'std::format_to': ambiguous call to overloaded function
C:\Program Files\Microsoft Visual Studio22\Community\VC\Tools\MSVC.32.31326\include\format(3046): note: could be '_OutputIt std::format_to<OutputIt,const double&,const double&>(_OutputIt,const std::_Basic_format_string<char,const double &,const double &>,const double &,const double &)' [found using argument-dependent lookup]
with
[
_OutputIt=fmt::v8::appender,
OutputIt=fmt::v8::appender
]
G:\bazel_output_base\execroot\de_vertexwahn\bazel-out\x64_windows-fastbuild\bin\external\fmt\_virtual_includes\fmt\fmt/core.h(3195): note: or 'OutputIt fmt::v8::format_to<OutputIt,const double&,const double&,0>(OutputIt,fmt::v8::basic_format_string<char,const double &,const double &>,const double &,const double &)'
with
[
OutputIt=fmt::v8::appender
]
flatland/tests/third_party/fmt_test.cpp(52): note: while trying to match the argument list '(OutputIt, const char [10], const double, const double)'
with
[
OutputIt=fmt::v8::appender
]
G:\bazel_output_base\execroot\de_vertexwahn\bazel-out\x64_windows-fastbuild\bin\external\fmt\_virtual_includes\fmt\fmt/core.h(713): note: see reference to function template instantiation 'auto fmt::v8::formatter<complex,char,void>::format<Context>(const complex &,FormatContext &)' being compiled
with
[
Context=fmt::v8::format_context,
FormatContext=fmt::v8::format_context
]
G:\bazel_output_base\execroot\de_vertexwahn\bazel-out\x64_windows-fastbuild\bin\external\fmt\_virtual_includes\fmt\fmt/core.h(1457): note: see reference to function template instantiation 'bool fmt::v8::detail::has_const_formatter<U,Context>(void)' being compiled
with
[
U=complex,
Context=fmt::v8::format_context
]
G:\bazel_output_base\execroot\de_vertexwahn\bazel-out\x64_windows-fastbuild\bin\external\fmt\_virtual_includes\fmt\fmt/core.h(1486): note: see reference to class template instantiation 'fmt::v8::detail::arg_mapper<Context>::formattable<const complex &,complex>' being compiled
with
[
Context=fmt::v8::format_context
]
G:\bazel_output_base\execroot\de_vertexwahn\bazel-out\x64_windows-fastbuild\bin\external\fmt\_virtual_includes\fmt\fmt/core.h(1697): note: see reference to alias template instantiation 'fmt::v8::detail::mapped_type_constant<complex,Context>' being compiled
with
[
Context=fmt::v8::format_context
]
G:\bazel_output_base\execroot\de_vertexwahn\bazel-out\x64_windows-fastbuild\bin\external\fmt\_virtual_includes\fmt\fmt/core.h(1858): note: see reference to function template instantiation 'unsigned __int64 fmt::v8::detail::encode_types<Context,complex,>(void)' being compiled
with
[
Context=fmt::v8::format_context
]
G:\bazel_output_base\execroot\de_vertexwahn\bazel-out\x64_windows-fastbuild\bin\external\fmt\_virtual_includes\fmt\fmt/core.h(3167): note: see reference to class template instantiation 'fmt::v8::format_arg_store<fmt::v8::format_context,complex>' being compiled
flatland/tests/third_party/fmt_test.cpp(59): note: see reference to function template instantiation 'std::string fmt::v8::format<complex&>(fmt::v8::basic_format_string<char,complex &>,complex &)' being compiled
G:\bazel_output_base\execroot\de_vertexwahn\bazel-out\x64_windows-fastbuild\bin\external\fmt\_virtual_includes\fmt\fmt/core.h(1696): error C2062: type 'unknown-type' unexpected
G:\bazel_output_base\execroot\de_vertexwahn\bazel-out\x64_windows-fastbuild\bin\external\fmt\_virtual_includes\fmt\fmt/core.h(1696): error C2144: syntax error: 'unknown-type' should be preceded by '('
G:\bazel_output_base\execroot\de_vertexwahn\bazel-out\x64_windows-fastbuild\bin\external\fmt\_virtual_includes\fmt\fmt/core.h(1697): error C2039: 'value': is not a member of '`global namespace''
G:\bazel_output_base\execroot\de_vertexwahn\bazel-out\x64_windows-fastbuild\bin\external\fmt\_virtual_includes\fmt\fmt/core.h(1855): error C3615: constexpr function 'fmt::v8::detail::encode_types' cannot result in a constant expression
G:\bazel_output_base\execroot\de_vertexwahn\bazel-out\x64_windows-fastbuild\bin\external\fmt\_virtual_includes\fmt\fmt/core.h(1858): note: failure was caused by control reaching the end of a constexpr function
Target //flatland/tests/third_party:fmt_test failed to build
Use --verbose_failures to see the command lines of failed build steps.
该代码似乎适用于 Ubuntu 20.04 上的 GCC9 以及 macOS 上的 Apple CLang。知道我在这里做错了什么吗?
错误是由C++20引入的std::format_to
函数引起的。要修复它,请限定您对 fmt::format_to
的调用。例如,而不是
return format_to(ctx.out(), "{0} +i{1}", number.a, number.b);
改为这样做:
return fmt::format_to(ctx.out(), "{0} +i{1}", number.a, number.b);
有关详细信息,请参阅此问题:format conflict with Visual Studio 2022 17.2.0。