如何将非可变参数值传递给 fmt::format?

Kyo*_*one 5 c++ formatting variadic variadic-functions fmt

我正在使用很棒的fmt C++ 库来更优雅地格式化字符串。

我想将一个非变量参数列表传递给fmt::format. 它可能是一个std::vector, 或std::string或其他任何形式,但它始终与格式字符串匹配。

所以fmt::format工作原理如下:

std::string message = fmt::format("The answer is {} so don't {}", "42", "PANIC!");
Run Code Online (Sandbox Code Playgroud)

但我想要的是这样的:

std::vector<std::string> arr;
arr.push_back("42");
arr.push_back("PANIC!");
std::string message = fmt::format("The answer is {} so don't {}", arr);
Run Code Online (Sandbox Code Playgroud)

有没有办法/解决方法来做到这一点?

Bar*_*rry 9

您可以vformat从您自己的vector. 这似乎有效:

std::string format_vector(std::string_view format,
    std::vector<std::string> const& args)
{
    using ctx = fmt::format_context;
    std::vector<fmt::basic_format_arg<ctx>> fmt_args;
    for (auto const& a : args) {
        fmt_args.push_back(
            fmt::internal::make_arg<ctx>(a));
    }

    return fmt::vformat(format,
        fmt::basic_format_args<ctx>(
            fmt_args.data(), fmt_args.size()));
}

std::vector<std::string> args = {"42", "PANIC!"};
std::string message = format_vector("The answer is {} so don't {}", args);
Run Code Online (Sandbox Code Playgroud)


Jar*_*d42 4

添加一个额外的层,例如:

template <std::size_t ... Is>
std::string my_format(const std::string& format,
                      const std::vector<std::string>& v,
                      std::index_sequence<Is...>)
{
    return fmt::format(format, v[Is]...);
}


template <std::size_t N>
std::string my_format(const std::string& format,
                      const std::vector<std::string>& v)
{
    return my_format(format, v, std::make_index_sequence<N>());
}
Run Code Online (Sandbox Code Playgroud)

用法是:

std::vector<std::string> arr = {"42", "PANIC!"};
my_format<2>("The answer is {} so don't {}", arr);
Run Code Online (Sandbox Code Playgroud)

您可能会获得有关operator ""_format编译时预期大小的信息