9

Is there a way to extend spdlog to support a custom struct as an item when formatting using {}?

So when I have a

struct p {
    int x;
    int y;
    int z;
};

p my_p;

I want to do

spdlog::info("p = {}", my_p);
// after registering some kind of formatter object for {p}

instead of

spdlog::info("p = (x={}, y={}, z={})", my_p.x, my_p.y, my_p.z);
pmf
  • 7,619
  • 4
  • 47
  • 77
  • 1
    The global name `_s` is reserved, check for "reserved identifiers in C++". That said, is there a documented way to extend spdlog? – Ulrich Eckhardt Nov 17 '19 at 09:03

2 Answers2

9

The accepted answer does not work anymore with newer versions of spdlog, fmt now requires specializing formatter<T> (see https://fmt.dev/latest/api.html#udt for details).

Using your p struct this is the formatter:

#include <spdlog/fmt/bundled/format.h>

template<>
struct fmt::formatter<p> {
    constexpr auto parse(format_parse_context& ctx) -> decltype(ctx.begin()) {
        return ctx.end();
    }

    template <typename FormatContext>
    auto format(const p& input, FormatContext& ctx) -> decltype(ctx.out()) {
        return format_to(ctx.out(),
            "(x={}, y={}, z={})",
            input.x, input.y, input.z);
    }
};

The parse method is used to read eventual format specifications, if you don't need them you can simply return ctx.end() and skip specifications like in the sample.

aghidini
  • 2,855
  • 5
  • 29
  • 32
  • I am on spdlog 1.10.0 (Apr 2022) and the accepted answer still works for me as long as `spdlog/fmt/ostr.h` is included. I wonder if it's fmt that requires this answer, but not spdlog, i.e. if you use fmt without spdlog? – Zitrax Nov 07 '22 at 10:18
  • @aghidini your example does not compile. It must be `input.x, input.y, input.z` instead of `p.` in format. – rherrmannr Mar 28 '23 at 07:25
4
#include "spdlog/spdlog.h"
#include "spdlog/fmt/ostr.h" // must be included

class some_class {};
std::ostream& operator<<(std::ostream& os, const some_class& c)
{ 
  return os << "some_class"; 
}

see https://github.com/gabime/spdlog/wiki/1.-QuickStart#log-user-defined-objects

GabiMe
  • 18,105
  • 28
  • 76
  • 113
  • Somehow missed this completely when looking through the documentation for exactly this ... – pmf Nov 19 '19 at 07:48
  • 3
    This solution does not work anymore in recent versions of spdlog. It seems you have to specialize a formatter now (following https://fmt.dev/latest/api.html#format-api). – sunmat Jun 02 '21 at 09:33