Yeah it's not great unfortunately. It ends up being that I have two sides of this code--one side is this subset that I've wondered about writing analysers for and checking the syntax just for this custom "dialect" almost. The other side is the impls of the APIs that side uses.
In general though I wonder how much the new 'concepts' stuff can help.
But yeah this is the closest I've come to having a UI DSL in a language with deterministic resource management and access to direct byte data layout for your structures. The main other alternative seems to be Rust and IME I've had a harder time with its error messages but I think it's also bc. I happen to have experience with 'old' C++. If I was starting fresh it'd be different.
The error messages produced by g++ for anything template related are a really difficult hurdle to overcome as a beginner. I am sure once you mastered it, it does make sense -- but right now it's a source of frustration for me.
I haven't used GCC in a while, but clang's template error msgs are way better than MSVC's in my experience. Still not like--good--haha. Like not Elm-level.
Yeah I'm looking forward to seeing how concepts work out in practice.
Also, to clarify on the original point, in this case it doesn't require that much template trickery. Most attributes could be handled as `.foo(Foos::BAR_1)` to set HTML attribute `foo="bar_1"` for example and have things still be 'type safe' on the C++ side. I just pass strings through right now to have a catch-all API, then I could go back on it after some real use and see what styles come in practice.
The only template it happens to use right now is the usual `template<typename F>` with `F &&f` to let you pass an inlineable lambda. I could use `static_assert` as you say, with `std::is_invocable_v`, and offer a nicer error message when that doesn't match.