C++ {fmt} 的 fmt::vformat 与宽字符串以及 fmt::make_wformat_args 无法编译通过。

huangapple go评论69阅读模式
英文:

C++ {fmt} fmt::vformat with wide-string and fmt::make_wformat_args fails to compile

问题

此代码无法编译。(error: no matching function for call to 'vformat(std::wstring&, fmt::v10::format_arg_store<fmt::v10::basic_format_context<std::back_insert_iterator<fmt::v10::detail::buffer<wchar_t> >, wchar_t>, int>)

#include <fmt/xchar.h>
#include <string>
#include <iostream>

int main() {
    int arg_1 = 12;
    std::wstring format = L"Hello {}";
    std::wstring test = fmt::vformat(format, fmt::make_wformat_args(arg_1));
    std::wcout << test;
    return 0;
}

然而,这段代码可以成功编译。

#include <fmt/xchar.h>
#include <string>
#include <iostream>

int main() {
    int arg_1 = 12;
    std::string format = "Hello {}";
    std::string test = fmt::vformat(format, fmt::make_format_args(arg_1));
    std::cout << test;
    return 0;
}

我正在使用 {fmt} 10.0.0 并包括 xchar.h,fmt::format 与宽字符串一起按预期工作,似乎只有 fmt::vformat 出现了问题。

我尝试过在不同配置下包含不同的独立 fmt 头文件(fmt/core.h,fmt/format.h,fmt/xchar.h)。这似乎毫无意义,因为 xchar.h 包含其他库的头文件。

虽然我专门使用 MSVC,但我尝试过并在 GCC 上遇到了相同的问题。

我尝试过使用 fmt::make_format_args

我还尝试过为 fmt::make_wformat_args 指定 fmt::wformat_context 模板参数。

我的具体用例要求我使用来自磁盘的本地化文件,因此我无法在编译时知道格式字符串。

英文:

This code fails to compile. (error: no matching function for call to &#39;vformat(std::wstring&amp;, fmt::v10::format_arg_store&lt;fmt::v10::basic_format_context&lt;std::back_insert_iterator&lt;fmt::v10::detail::buffer&lt;wchar_t&gt; &gt;, wchar_t&gt;, int&gt;)&#39;)

#include &lt;fmt/xchar.h&gt;
#include &lt;string&gt;
#include &lt;iostream&gt;

int main() {
    int arg_1 = 12;
    std::wstring format = L&quot;Hello {}&quot;;
    std::wstring test = fmt::vformat(format, fmt::make_wformat_args(arg_1));
    std::wcout &lt;&lt; test;
    return 0;
}

However, this code successfully compiles.

#include &lt;fmt/xchar.h&gt;
#include &lt;string&gt;
#include &lt;iostream&gt;

int main() {
    int arg_1 = 12;
    std::string format = &quot;Hello {}&quot;;
    std::string test = fmt::vformat(format, fmt::make_format_args(arg_1));
    std::cout &lt;&lt; test;
    return 0;
}

I am using {fmt} 10.0.0 and including xchar.h, fmt::format works as I would expect with wide strings, it seems I am facing this problem with only fmt::vformat.

I have tried including various separate fmt header files in different configurations (fmt/core.h, fmt/format.h, fmt/xchar.h). This seems pointless as xchar.h includes the other libraries header files.

While I specifically use MSVC, I have tried and have had the same issue on GCC.

I have tried using fmt::make_format_args instead.

I have also tried specifying the fmt::wformat_context template parameter for fmt::make_wformat_args.

My specific use case has me using localization files from disk, so I cannot know the format strings at compile time.

答案1

得分: 5

你不应该在自己没有编写格式化函数的情况下使用 fmt::vformat。在运行时才知道的格式字符串的正确传递方式是将其包装在 fmt::runtime 中,并调用 fmt::format

#include <fmt/xchar.h>
#include <iostream>

int main() {
  int arg_1 = 12;
  std::wstring format = L"Hello {}";
  std::wstring test = fmt::format(fmt::runtime(format), arg_1);
  std::wcout << test;
}

https://godbolt.org/z/4WKd575o7

英文:

You shouldn't be using fmt::vformat except when writing a formatting function yourself. A proper way to pass a format string only known at runtime is by wrapping it in fmt::runtime and calling fmt::format:

#include &lt;fmt/xchar.h&gt;
#include &lt;iostream&gt;

int main() {
  int arg_1 = 12;
  std::wstring format = L&quot;Hello {}&quot;;
  std::wstring test = fmt::format(fmt::runtime(format), arg_1);
  std::wcout &lt;&lt; test;
}

https://godbolt.org/z/4WKd575o7

答案2

得分: 1

vformat的第一个参数是一个字符串视图。似乎<fmt/xchar.h>添加了一个重载,如下:

template<typename Char>
std::basic_string<Char> fmt::vformat(fmt::basic_string_view<Char>, basic_format_args<some_non_deduced_context>);

因此,Char 无法从 std::basic_string<wchar_t> 推断出来,你需要一个实际的 fmt::basic_string_view

std::wstring test = fmt::vformat(fmt::wstring_view(format), fmt::make_wformat_args(arg_1));
英文:

vformat's first argument is a string view. Seems like &lt;fmt/xchar.h&gt; adds an overload like:

template&lt;typename Char&gt;
std::basic_string&lt;Char&gt; fmt::vformat(fmt::basic_string_view&lt;Char&gt;, basic_format_args&lt;some_non_deduced_context&gt;);

So Char can't be deduced from std::basic_string&lt;wchar_t&gt;, and you need an actual fmt::basic_string_view:

std::wstring test = fmt::vformat(fmt::wstring_view(format), fmt::make_wformat_args(arg_1));

huangapple
  • 本文由 发表于 2023年5月28日 19:14:01
  • 转载请务必保留本文链接:https://go.coder-hub.com/76351196.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定