{fmt}สามารถ implicitly แปลงเรียนแต่ไม่ใช่ของเว็กเตอเรียนชั้นเรียนนั่น

0

คำถาม

ดังนั้นฉันต้องต่อไปนี้ 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;
};

ถ้าฉันประกาศ Snowflake snowflake = 336227221100429313; งั้นฉันสามารถใช้ได้ fmt::print("Snowflake: {}", snowflake); ตัวอย่างเช่นนโอเคแต่ฉันไม่สามารถใช้ std::vector<Snowflake> snowflakes{164234463247597568, 106615803402547200, 268487751370801152}; กับ fmt::print("Snowflakes: {}", snowflakes); ฉันเอาตามข้อผิดพลาดคือ:

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,
      |       ^~~~~~~~~~~

ฉันพยายามประกาศว่ากองต่อไปนี้:

template <> struct fmt::formatter<Snowflake> : formatter<uint64_t> {
    template <typename FormatContext>
    auto format(Snowflake s, FormatContext &ctx) {
        return formatter<uint64_t>::format(s, ctx);
    }
};

แต่นั่นยังไม่ได้แก้ปัญหา. ฉันต้อง celare น fmt::formatter สำหรับ std::vector<Snowflake>? อะไรจะเป็นหนทางที่ง่ายที่สุดที่จะทำอย่างนั้น?

c++ fmt implicit stdvector
2021-11-13 15:49:48
1

คำตอบที่ดีที่สุด

1

มันทำงานอยู่ในปัจจุบันเวอร์ชั่นของ{fmt}(https://godbolt.org/z/98qzcb8r9):

#include <fmt/ranges.h>

...

auto snowflake = Snowflake(336227221100429313);
fmt::print("Snowflake: {}\n", snowflake);
auto snowflakes = std::vector<Snowflake>{164234463247597568, 106615803402547200, 268487751370801152};
fmt::print("{}\n", snowflakes);

รอยนิ้วมือ

Snowflake: 336227221100429313
[164234463247597568, 106615803402547200, 268487751370801152]

นๆมาขึ้นอยู่กับที่แยกกำหนดการแปลงไม่ได้แนะนำนะ

2021-11-14 14:33:19

อาจจะคุ้มที่จะพูดถึงเรื่องในคำตอบเองนั่น #include <fmt/ranges.h> คือต้องการสำหรับเรื่องนี้ซึ่งตรงข้ามกับแค่ #include <fmt/format.h> หรือ <fmt/core.h>.
Nathan Pierson

@NathanPierson ใช่นั่นเเหล่ะเรื่องของเรื่อง รวมทั้งเรื่องนั้นด้วซ่อมมัน! ควรจะนั่งไปในคำตอบด้วยตัวมันเองหรือควรเรื่องนี้จะถูกแก้ไข?
Aido

เพิ่มคนรวมเช่นกัน
vitaut

ในภาษาอื่นๆ

หน้านี้อยู่ในภาษาอื่นๆ

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................

ดังอยู่ในนี้หมวดหมู่

ดังคำถามอยู่ในนี้หมวดหมู่