C++ {fmt} fmt::vformat with wide-string and fmt::make_wformat_args无法编译

ogq8wdun  于 2023-05-30  发布在  其他
关注(0)|答案(2)|浏览(208)

此代码无法编译。(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模板参数。
我的特定用例让我使用磁盘中的本地化文件,因此我无法在编译时知道格式字符串。

oipij1gg

oipij1gg1#

除非你自己写格式化函数,否则不应该使用fmt::vformat。传递仅在运行时已知的格式字符串的正确方法是将其 Package 在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

kx7yvsdv

kx7yvsdv2#

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));

相关问题