Announcement

Collapse
No announcement yet.

C++17 Is Now Official

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • #41
    Originally posted by hoohoo View Post

    I've been making use of this lately. It is a good example of what I call abuse of lambdas:

    https://github.com/eidheim/Simple-We...s_examples.cpp

    I've tried pasting the verbatim code, but I can't seem to get the forum to display it nicely.
    Hah, that's funny. Indeed, lambdas absolutely useless there. It's readable though, but I admit it's readable by an accident — if the author would additionally mix it with variables and calculations, it would turn into a spaghetti for sure.

    Comment


    • #42
      Originally posted by Hi-Angel View Post
      Well, in this particular case it does make sense to use explicit return value. That said, I would generally refrain of using "auto" as a return type in favor of templates, because templates are imposing constraints on what exactly one wanted to return. And in case of templates you'd get again return T(1, 2, "thread1"); which doesn't tell you much.
      I like templates - because they constrain things, and they express concepts better IMHO than inheritance. They can be obscure too though, through verbosity.

      Comment


      • #43
        Originally posted by hoohoo View Post

        I like templates - because they constrain things, and they express concepts better IMHO than inheritance. They can be obscure too though, through verbosity.
        Yeah, I agree, templates sometimes can be quite hard to read. I have this decoder in my head though which is called Haskell, it makes work with templates easier. Haskell is a very elegant, both syntax and ideas -wise, language, I recommend learning it. Knowing Haskell might give lots of insights into a better design. I'm even using pseudo-haskell for prototyping a code that I am not sure yet how to write, before making an actual implementation in whatever other language I'm using. And I assure you, my Haskell-foo is far from being good.
        Last edited by Hi-Angel; 12-06-2017, 02:18 AM.

        Comment


        • #44
          Originally posted by hoohoo View Post
          - C++11 added lambda expressions... now I regularly find open source software (and sometimes closed source in the work place) where an entire program is implemented in essentially one function using lambdas to differentiate execution paths. Many dozens, to hundreds, of lines in each lambda, it's incredibly hard to read, and neither Slickedit nor Notepad++ can auto-format this kind of code well. It's worse than spaghetti code implemented with goto. In fact lambdas seem to encourage this Javascript style code. Lambdas are intrinsically antithetical to the idea of structured code.
          Yes, that's likewise been a challenge in Java since lambda syntax was added in 8. They're an immensely useful addition to the language, but that usefulness does see a lot of abuse. I recently found myself writing a piece of code (just a couple of dozen lines) that consisted of four nested lambdas executing in three different thread pools - that quickly got rewritten once I realised I couldn't easily tell which thread any given line of code was going to run in...

          Comment


          • #45
            Originally posted by toojays View Post
            The price of the final standard is set by the ISO, who own the copyright. Pretty much all practitioners refer to the final draft, which is free.
            Assuming these proceeds go to support ISO, I'd say buy an official copy if you or your employer can afford it.

            Comment


            • #46
              Originally posted by Hi-Angel View Post
              Yeah, I agree, templates sometimes can be quite hard to read. I have this decoder in my head though which is called Haskell, it makes work with templates easier. Haskell is a very elegant, both syntax and ideas -wise, language, I recommend learning it. Knowing Haskell might give lots of insights into a better design. I'm even using pseudo-haskell for prototyping a code that I am not sure yet how to write, before making an actual implementation in whatever other language I'm using. And I assure you, my Haskell-foo is far from being good.
              Haskell is nice. I don't get to use it much in practice though, my jobs have always mandated C++ or Java or the then-current melange of web programming languages.

              Comment


              • #47
                Originally posted by Hi-Angel View Post
                I am simply saying that there's no need to be explicit about the return type, because it is clear anyway.


                Ah, well. It works with a constructor too, see, quick'n'dirty example:
                Code:
                struct MyJITThread {
                int fd;
                const char* name;
                
                MyJITThread(int fdArg, const char* nameArg, int pidArg):
                pid(pidArg), fd(fdArg), name(nameArg) {}
                MyJITThread(int fdArg, const char* nameArg, MyJITThread& thr):
                pid(thr.pid), fd(fdArg), name(nameArg) {}
                private:
                int pid;
                };
                
                int main() {
                MyJITThread thr1 = {fd: 1, name: "thread1", pid: 2};
                MyJITThread thr2 = {fd: 1, name: "thread2", thread: thr1};
                }
                Problem is, that this is NOT C++, but "GNU C++", those named initializers are not part of the standard but a gnu extension. Compile with "-std=c++17 -pedantic" should you believe your compiler more than me.

                Comment


                • #48
                  Originally posted by discordian View Post

                  Problem is, that this is NOT C++, but "GNU C++", those named initializers are not part of the standard but a gnu extension. Compile with "-std=c++17 -pedantic" should you believe your compiler more than me.
                  Wow, indeed, stupid gcc This is probably a bug, because I don't use -std=gnu++17, I explicitly use -std=c++17.

                  Comment


                  • #49
                    Originally posted by Hi-Angel View Post
                    E.g. if you're iterating over the vector and changing it at the same time — obviously "iterators are unsafe"
                    I think the problem for me is that in many cases in a large software codebase you cannot "guarantee" that you (or some other developer) is not changing the vector you are iterating through. It might be down a very long code path that happens to clear the entire vector. Yes, the ::at(size_t) solution will still have issues with this, i.e you might end up skipping over certain entries but at least it will not cause "undefined behavior".

                    Now don't get me wrong, I really do want to use iterators since they (or many of the new features of C++11+) are really clean and convenient. However if the "guaranteed" safety is not there I can't quite justify it.

                    Something like Microsoft's "Safe iterators" would be cool but as an actual standard of the language rather than some vendor specific hackup job (or DUMA / mprotect).

                    (though I still don't like async code. I don't think it is suitable for a lot of use-cases where the execution does need to block until a task is complete. Games and systems level development (i.e what C++ excels at) comes to mind.
                    Last edited by kpedersen; 12-09-2017, 01:03 PM.

                    Comment


                    • #50
                      Originally posted by kpedersen View Post

                      I think the problem for me is that in many cases in a large software codebase you cannot "guarantee" that you (or some other developer) is not changing the vector you are iterating through. It might be down a very long code path that happens to clear the entire vector. Yes, the ::at(size_t) solution will still have issues with this, i.e you might end up skipping over certain entries but at least it will not cause "undefined behavior".
                      Can you "guarantee" that any reference (even this) in your local scope is still valid after calling any function?
                      This is a generic problem and not one of iterators, commonly you define layers and don't permit touching objects from lower levels so that you CAN "guarantee" calling a function wont affect "its basement" by following a set of rules you can verify for each part of the software.

                      No language will prevent you from creating a hell of dependencies and side-effects (maybe LISP and Haskell are different).

                      Comment

                      Working...
                      X