简体   繁体   English

使用 fmt 库自定义 std::vectors 元素的格式

[英]Custom formatting of the elements of std::vectors using the fmt library

While I can use <fmt/ranges.h> to readily output the contents of a std::vector<T> , I'm at a loss to format the display of its elements according to my preferences.虽然我可以使用<fmt/ranges.h>轻松 output 的内容std::vector<T> ,但我无法根据自己的喜好格式化其元素的显示。

#include <fmt/core.h>
#include <fmt/ranges.h>

int main() {
    double x1 = 1.324353;
    double x2 = 4.432345;
    std::vector<double> v = {x1, x2};
    fmt::print("{}\n", v); // OK [1.324353, 4.432345]
    fmt::print("{:+5.2}\n", x1); // OK +1.3
    // fmt::print("{:+5.2}\n", v); // Does not compile!
    return EXIT_SUCCESS;
}

The program outputs:程序输出:

[1.324353, 4.432345]
 +1.3

but is missing the desired output from the commented out line in my code above但在我上面的代码中的注释行中缺少所需的 output

[ +1.3, +4.4]

I then tried implementing a custom formatter for vectors of ordinary type but my attempt comes up short:然后我尝试为普通类型的向量实现自定义格式化程序,但我的尝试失败了:

// custom formatter for displaying vectors
template <typename T>
struct fmt::formatter<std::vector<T>> : fmt::formatter<T> {
    constexpr auto parse(format_parse_context &ctx) {
        return ctx.begin();
    }

    template <typename FormatContext>
    auto format(std::vector<T> v, FormatContext &ctx) {
        std::vector<std::string> v_str;
        v_str.reserve(v.size());
        const auto fmt_str = [&]() {
            if constexpr (std::is_integral<T>::value) {
                return "{:+5}";
            } else if constexpr (std::is_floating_point<T>::value) {
                return "{:+5.2}";
            } else {
                return "{}";
            }
        }();
        for (auto &e : v) {
            v_str.push_back(fmt::format(fmt_str, e));
        }
        return format_to(ctx.out(), "{}", v);
    }
};

The compiler complains编译器抱怨

type_traits:3174:38: error: ambiguous partial specializations of 'formatter<std::vector<double>>'
    : public integral_constant<bool, __is_constructible(_Tp, _Args...)>

How do I get the fmt library to display the contents of a vector with custom formatting?如何让fmt库以自定义格式显示矢量的内容? The version I'm currently using is 8.1.1 .我目前使用的版本是8.1.1

You can do it as follows:你可以这样做:

std::vector<double> v = {1.324353, 4.432345};
fmt::print("{::+5.2}\n", v);

This prints:这打印:

[ +1.3,  +4.4]

godbolt神螺栓

Note the extra : .注意额外的: Format specifiers after the first colon (empty in this case) apply to the vector itself.第一个冒号之后的格式说明符(在这种情况下为空)适用于向量本身。 Specifiers after the second colon ( +5.2 ) apply to elements.第二个冒号 ( +5.2 ) 之后的说明符适用于元素。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM