Comment by ChristianJacobs

12 hours ago

You're not wrong there. The late stage (compilation wise) of template instantiation doesn't help either, as so much context has been built up. The art of debugging C++ compiler output is knowing which 90% to ignore. If you read it all you'll simply go mad.

Concepts at least tells you which criteria you didn't satisfy (as long as the concept is correct...), which - admittedly - feels like putting a bandaid on bullet wound.

Even without having concepts, a cpp compiler could conceivably detect at definition time that the template is acting as a generics declaration only, and treat it specially as if it was a "late-bound concept". That would potentially help with codegen, but it would certainly help with making compile errors better. I find it is hard to convince compiler engineers to divorce themselves from what the language semantics are and what the compiler does. As long as the user visible behavior is the same, you can internally handle things differently for conceptually this same feature.

Rust has the same problem as templates with macros. We haven't had a strong need to customize the macrosl evaluation much, but I could very much see us special casing macros that are function like, or have macro arms that can only be a handful of things in order treat them different so diagnostics get better. The only thing that comes to mind thar we do today, is that when a macro call falls through (no macro arm matches), we retry it adding commas in between expressions to see if it was just a typo.

Concepts could be much better, but first we only got the light version, and secondly the effort hasn't been there regarding improving the error messages.

Also, so far I would say they haven't been getting people rushing out to use them anyway, as C++20 is still too new for many projects.

Even GCC only now changed to C++20 as default mode.

Concepts have been disappointing for me: what they tell you is still buried in 1000 lines of errors.

  • Concepts support (like traits I'm Rust) is necessary for good diagnostics, but not sufficient. It gives you the architecture and metadata that you require to infer what the user wants, but a lot of additional analysis on the decision chain that was followed in order to figure out what is relevant and what isn't.

    • Also the C++ 20 "Concepts Lite" isn't a nominal system like Rust's traits (or like the C++ 0x Concepts proposal which Bjarne had ripped out), it's Duck typing again and so it's harder even if the work was done.

      Rust can say hey, this code treats Mallard as if it's a Duck, did you mean for this Mallard to implement Duck? If so, try writing #[derive(Duck)]

      But for Concepts Lite the compiler needs to guess that you wanted Mallard to match this requirement that Ducks can quack, and observe that Mallard's quack has a slightly wrong signature so it doesn't match and so that's probably the mistake.

  • concepts have been excellent for me for overload resolution in complex template code (good riddance SFINAE) and for documentation.

    To improve error messages, not so much.