簡體   English   中英

如何將非可變值傳遞給 fmt::format?

[英]How to pass not variadic values to fmt::format?

我正在使用很棒的fmt C++ 庫來更優雅地格式化字符串。

我想將一個非變量 arguments 列表傳遞給fmt::format 它可以是std::vectorstd::string或其他任何東西,但它始終與格式字符串匹配。

所以fmt::format的工作方式如下:

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

但我想要的是這樣的:

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

有沒有辦法/解決方法這樣做?

添加一個額外的圖層,例如:

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

用法是:

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

使用operator ""_format您可能會在編譯時獲得有關預期大小的信息

您可以從vector自行構建vformat的參數。 這似乎有效:

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

在當前版本 (8.1.1) 中,以下是可能的;

fmt::dynamic_format_arg_store<fmt::format_context> ds;

ds.push_back(42);
ds.push_back("PANIC");

std::string msg = fmt::vformat("The answer is {} so don't {}", ds);

如果不對 fmt 庫進行更改,這看起來是不可能的。 fmt::format調用fmt::vformat ,它采用fmt::format_argsfmt::wformat_args對象表示多個參數,但提供的創建format_argswformat_args對象的唯一方法是通過另一個可變參數函數,這意味着在編譯時必須知道參數。

因此,您可以編寫一個包裝器來解壓縮std::tuplestd::array並將其元素傳遞給fmt::format ,因為這些元素的數量和類型在編譯時是已知的。 但是你不能對std::vectorstd::list等做同樣的事情,因為這些容器的大小在運行時可能會有所不同。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM