Deci am urmatoarele struct
:
struct Snowflake {
Snowflake() : _value(0) {}
Snowflake(uint64_t value) : _value(value) {}
Snowflake(std::string value) : _value(std::stoull(value)) {}
Snowflake(const Snowflake &) = default;
operator uint64_t &() { return _value; }
operator uint64_t() const { return _value; }
operator std::string() const { return std::to_string(_value); }
Snowflake &operator=(uint64_t val) {
_value = val;
return *this;
}
Snowflake &operator=(const std::string &str) {
_value = std::stoull(str);
return *this;
}
Snowflake &operator=(const Snowflake &s) {
_value = s._value;
return *this;
}
protected:
uint64_t _value;
};
Dacă am declara Snowflake snowflake = 336227221100429313;
pot folosi fmt::print("Snowflake: {}", snowflake);
de exemplu, doar bine, dar nu-l pot folosi std::vector<Snowflake> snowflakes{164234463247597568, 106615803402547200, 268487751370801152};
cu fmt::print("Snowflakes: {}", snowflakes);
I a lua următoarea eroare:
In file included from -snip-/cmake-build-debug/_deps/fmt-src/include/fmt/format.h:48,
from -snip-/snowflake.hh:8,
from -snip-/main.cpp:2:
-snip-/cmake-build-debug/_deps/fmt-src/include/fmt/core.h: In instantiation of ‘constexpr fmt::v8::detail::value<Context> fmt::v8::detail::make_arg(T&&) [with bool IS_PACKED = true; Context = fmt::v8::basic_format_context<fmt::v8::appender, char>; fmt::v8::detail::type <anonymous> = fmt::v8::detail::type::custom_type; T = std::vector<Snowflake>&; typename std::enable_if<IS_PACKED, int>::type <anonymous> = 0]’:
-snip-/cmake-build-debug/_deps/fmt-src/include/fmt/core.h:1807:77: required from ‘constexpr fmt::v8::format_arg_store<Context, Args>::format_arg_store(T&& ...) [with T = {std::vector<Snowflake, std::allocator<Snowflake> >&}; Context = fmt::v8::basic_format_context<fmt::v8::appender, char>; Args = {std::vector<Snowflake, std::allocator<Snowflake> >}]’
-snip-/cmake-build-debug/_deps/fmt-src/include/fmt/core.h:1824:38: required from ‘constexpr fmt::v8::format_arg_store<Context, fmt::v8::remove_cvref_t<Args>...> fmt::v8::make_format_args(Args&& ...) [with Context = fmt::v8::basic_format_context<fmt::v8::appender, char>; Args = {std::vector<Snowflake, std::allocator<Snowflake> >&}]’
-snip-/cmake-build-debug/_deps/fmt-src/include/fmt/core.h:3156:44: required from ‘void fmt::v8::print(fmt::v8::format_string<T ...>, T&& ...) [with T = {std::vector<Snowflake, std::allocator<Snowflake> >&}; fmt::v8::format_string<T ...> = fmt::v8::basic_format_string<char, std::vector<Snowflake, std::allocator<Snowflake> >&>]’
-snip-/main.cpp:10:44: required from here
-snip-/cmake-build-debug/_deps/fmt-src/include/fmt/core.h:1680:7: error: static assertion failed: Cannot format an argument. To make type T formattable provide a formatter<T> specialization: https://fmt.dev/latest/api.html#udt
1680 | formattable,
| ^~~~~~~~~~~
Am încercat declarând următoarele:
template <> struct fmt::formatter<Snowflake> : formatter<uint64_t> {
template <typename FormatContext>
auto format(Snowflake s, FormatContext &ctx) {
return formatter<uint64_t>::format(s, ctx);
}
};
dar asta nu a rezolvat problema. Am nevoie pentru a celare o fmt::formatter
pentru std::vector<Snowflake>
? Ce ar fi cel mai simplu mod de a face asta?
#include <fmt/ranges.h>
este necesar pentru acest lucru, spre deosebire de doar#include <fmt/format.h>
sau<fmt/core.h>
.