ITADN

Forward declaration headers to improve compilation speed for projects that use glaze

#2525Closedstephenberry 创建于 2026-04-23
S
stephenberrycommented
### Discussed in https://github.com/stephenberry/glaze/discussions/2524 <div type='discussions-op-text'> <sup>Originally posted by **cout** April 22, 2026</sup> On my development machine, just including `<glaze/glaze.hpp>` adds 6.8 seconds to my build for each translation unit that includes that file. This is using clang with -Og, and all I am doing is including the header. I have many types for which I want to specialize `glz::meta`, `glz::from`, or `glz::to`. For non-struct types, these are simple lambda functions or type aliases, so forward declaring them in a header makes sense, and I don't have to include any glaze headers: ``` namespace glz { template <typename T> struct meta; template <uint32_t Format, typename T> struct to; template <uint32_t Format, typename T> struct from; template <uint32_t Format> struct serialize; template <uint32_t Format> struct parse; template <class T, class From, class To> struct custom_t; } ``` (side note: it might be a good idea to add a type alias for that uint32_t format type) Since I have a few classes where I want to use `glz::custom`, I've written my own wrapper that does not require including any of glaze: ``` template <auto From, auto To> constexpr auto my_custom = []() noexcept { return [](auto && v) { return glz::custom_t { v, From, To }; }; }(); ``` (no deduction guide needed, since the lambda does not get evaluated until I call `read_json` or `write_json`, and the translation unit where I do that includes all the important bits of glaze) For struct types, since we are not yet using reflection, I also wanted to use `glz::object` without including `<glaze/core/common.hpp>`, which adds about 4 seconds to the compile time. But this does not work -- I need `glz::detail::Object` or a specialization of it. I started going down that rabbit hole anyway, and made a tagged specialization of `Object`, then I realized I need to pull in `glaze/tuple/tuple.hpp` as well. I've decided this is probably more brittle than I want. Suggestion: * Provide headers that forward-declare any types that might get specialized * Separate functions and types used to specialize `glz::meta` from those used to interpret `glz::meta`. * Be aware of which standard library headers are more expensive to include (iostream, fstream, chrono, filesystem, and complex are some of the more egregious, followed by ranges and iterator For discussion: * What parts of glaze are most used when specializing meta/to/from? * What parts of glaze are most conducive to splitting out into separate header files? * What parts of glaze are included by default, but include expensive standard library headers, and could be split out? (core/chrono.hpp comes to mind) * Are there better ways to define meta alongside my classes without pulling in all of glaze core?</div>
关闭于 2026-05-10 0 条评论