Forward declaration headers to improve compilation speed for projects that use glaze
### 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 条评论