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.
#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
[ +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? The version I'm currently using is 8.1.1
.