• voodooattack@lemmy.worldOP
      link
      fedilink
      arrow-up
      9
      ·
      edit-2
      2 days ago

      Back when I made this, GCC/clang were crashing left and right while compiling my project because of constexpr and auto usage with nested lambdas. It got worse with every template being evaluated until the compiler and my IDE started crashing.

      I was making a react-like UI component library with all the new bells and whistles of modern C++. It was fun at first then the issues cropped up and it kinda killed my passion for the language and drove me away entirely.

      Not sure about its state nowadays though.

      • DickFiasco@sh.itjust.works
        link
        fedilink
        arrow-up
        15
        ·
        2 days ago

        I see. I think auto gets overused a lot by people just being lazy about writing out the full type, but constexpr is good practice in my opinion. Never had a compiler issue with them, but then I don’t think I’ve ever used a nested lambda either.

        • voodooattack@lemmy.worldOP
          link
          fedilink
          arrow-up
          2
          ·
          edit-2
          15 hours ago

          The problem is that lambdas with a capture aren’t strongly typed are uniquely typed, so you have to use decltype/auto. And if you pass such a lambda to a function you’ll have to use auto as well.

          If you write a lambda with a capture that calls itself recursively you’ll have to pass it to itself as an auto argument as part of the call signature.

          I think this article explains it better: https://artificial-mind.net/blog/2020/09/12/recursive-lambdas

          Edit: fixed wrong terminology

        • thebestaquaman@lemmy.world
          link
          fedilink
          arrow-up
          6
          ·
          edit-2
          1 day ago

          I really like C++ (I know, shoot me), and I think auto should be avoided at (almost) all costs.

          One of the things I love about a language like C++ is that I can take one glance at the code and immediately know what types I’m working with. auto takes that away while adding almost no benefit outside of a little convenience while writing.

          If I’m working with some very big template type that I don’t want to write out, 99/100 times I’ll just have a using somewhere to make it more concise. Hell, I’ll have using vectord = std::vector<double> if I’m using a lot of them, because I think it makes the code more readable. Just don’t throw auto at me.

          Of course, the worst thing ever (which I’ve seen far too often) is the use of auto in examples in documentation. Fucking hell! I’m reading the docs because I don’t know the library well! When you first bother to write examples, at least let me know the return type without needing to dig through your source code!

            • thebestaquaman@lemmy.world
              link
              fedilink
              arrow-up
              2
              ·
              1 day ago

              Thanks, that was a good read :)

              However, my impression is that he’s largely using the existence of templates and polymorphism as arguments that “we don’t really care about type”. I disagree: A template is essentially a generic type description that says something about what types are acceptable. When working with something polymorphic, I’ll prefer ParentClass&, to indicate what kind of interface I’m working with.

              Sure, it can be very useful to hide exact type information in order to generalise the code, but I think that’s a weak argument for hiding all type information by default, which is what auto does.

              • ugo@feddit.it
                link
                fedilink
                arrow-up
                1
                ·
                5 hours ago

                auto doesn’t really hide all type information, but that is besides the point. The point is that in the vast majority of cases you don’t really care about the specific types your code is dealing with, you only care about the properties of the type.

                If I write get_descriptors()[some_idx] what is the type returned by get_descriptors()? You can’t know, because nothing tells you, but you know it must be a type that supports random access indexing. If I put the result of the function call in a for loop, it must support iteration. If I return it by move, it must support being moved.

                99% of code is like this. Then you have specialised code that might be doing bit wrangling and what not, in which case you must know that you are dealing exactly with, say, an uint32_t and not just something that supports left shift.

                For the 99% of cases, auto makes the code simpler, more correct, more robust, more consistent, and shorter to write and read.

                The post I replied to in particular got angry at documentation that uses auto. I have written documentation that looks like this

                auto my_var = MyConcreteType { /* … */ };
                auto const* x = my_var.get<uint32_t>();
                auto const& y = my_var.get_or<uint32_t>(42);
                

                How would such code benefit from not using auto?

                MyConcreteType my_var = MyConcreteType {}; just repeats the type, adds zero useful info.

                MyConcreteType my_var {}; is inconsistent. Where is the equal sign signifying that this is an assignment?

                Similarly, what would you gain by saying uint32_t const* x = my_var.get<uint32_t>();? Nothing, you just doubled your maintenance when you need to change the type passed to the template parameter.