Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I know why I don't like C++ anymore, it's just no fun.Its slow to compile, the errors are like 6 lines long full of template and class hierarchy that makes it hard to understand what exactly happened, and then of course there's the common coding shortcut of declaring everything auto. (What type is this list? I don't know, it's auto all the way down.) Then there's the whole thing about making constructors, but leaving the bodies empty because everything should be on initialize lists now, and now there's wrapped pointers for some reason.

I hated writing modern C++. It was just so depressing and frustrating.



My personal rules for using auto. Only use it iff:

1. the actual type is clearly visible on the right hand side. auto f = make_widget(); // it's a widget auto i = 123; // it's an int auto x = vec3(1.0, 0.0, 0.0); // it's a vector

2. the actual type doesn't really matter so much or is complicated to type out. auto it = vec.begin(); // it's an iterator auto it = // some template expression

3. the actual type is not known i.e. lambdas


I'm not a huge fan of the first rule. It's valid as stated, but the examples are questionable. I've seen all those in real code, and they're kind of annoying.

    auto f = make_widget();
    // is f of type widget or widget*?

    auto i = 123;
    // ok, I guess, but...
    // int i = 123; is shorter and more clear.

    auto x = vec3(1.0, 0.0, 0.0);
    // this can be shorter and simpler.
    // vec3 x(1.0, 0.0, 0.0);


These are good rules – as in liquor advertisements, it’s advisable to always accompany a declaration that uses `auto` with a rejoinder in the comments to Please Enjoy Responsibly


In a word where most new code is JavaScript, just use auto everywhere. It will be OK.


> Then there's the whole thing about making constructors, but leaving the bodies empty because everything should be on initialize lists now, and now there's wrapped pointers for some reason.

I fail to see how this line is supposed to be a "criticism" of modern C++.


It is funny that people on HN are so critical of `auto` when many people here are also coding in Ruby, Python, Swift and Javascript. Is the intersection between the two groups that small?


I still like it a lot.

However I have came to realize that I rather use it on as an infrastructure language.

Just when I need to write portable code across mobile OSes without dependencies on third party SDKs, interact with LLVM or give an helping hand to my actual daily programming languages.


Swift solves the "auto" issue pretty nicely - with the help of the IDE:

let x = someFunction()

Alt-click on x and it shows the type.

Otherwise, as you say, the code becomes very confusing and I abstain from auto except in cases where the type is clearly obvious.


Visual Studio shows the type of auto on hover.


… also one of the forthcoming Clang projects is a static-analysis tool (á la `clang-format`) for replacing any `auto` decls with the actual typename, so you can write lazy code without appearing unscrupulous at code reviews


I had to write C++ yesterday and hated every second of it, from the clunky header files, to the errors that make no sense, to the can't make a cyclic dependency between classes i.e.

      class A { B: b}
      class B { a: A}
Long story short - I was to create a wrapper around a Poco::Runnable, so you can use the wrapper as a Poco::Runnable (don't ask why, it's TEH LAW) but without extending it.


C++noob here, but: Given that the members in your example are no pointers but actual substructures within your data structure, wouldn't that result in an infinite data structure? Therefore it sewms quite logical to me it's not allowed.

Disallowing cyclical dependencies via pointer would make no sense though.


Right. C++ objects are values, not references to values like in almost all other languages. So C++ needs to know the sizes of everything to construct them. If you tried to write out the mathematical series describing the ultimate size you would need to allocate for A or B, you would end up with a value approaching infinity.


This is probably my favorite thing about C++. Values are so much easier to reason about than references.


It's more of a simplification. Although, I did try references and they didn't compile either. In fact, if I remember correctly the error was "forward declaration forbidden".

After spending about 10-12 years away from C++, I was pretty much on novice level. I remember some things, but most details and day to day specifics are gone. It did serve as a fresh reminder why I hate C++. Or more precisely, why I hate C++ compilers.


You can only do that when using pointers or references:

    class B;
    class A {
      B* b;
    }
    class B {
      A* a;
    }
because the compiler can (obviously) not tell how large the instances of the other class are when you have a field of that type. Remember that the class layout has to be fixed at compile time and both instance sizes depend on one another. That's not solvable.

C# does the same, actually:

    struct A {
      B b;
    }
    struct B {
      A a;
    }
will cause the following error:

    test.cs(2,5): error CS0523: Struct member 'A.b' of type 'B' causes a cycle in the struct layout
    test.cs(6,5): error CS0523: Struct member 'B.a' of type 'A' causes a cycle in the struct layout
with classes and references it works, of course:

    class A {
      B b;
    }
    class B {
      A a;
    }


This is also what I attempted, and as I remember it didn't work either, though to be honest I was really worn out fighting the obscure compiler errors by that point, I might have missed a sigil somewhere.

I spent good solid 30min trying to understand why defining and not defining my constructor was causing issues, to realize that the constructor error was actually a previous error, somewhere above the constructor.

Rust, also notes where and how you created an infinite loop.


Your compile error is likely because you use references instead of pointers. Reference as a class member is really hard to get right because it can be initialized only once, and cannot be copied or moved.


Not sure what you're trying to do, but:

    class A; class B; // 'forward declaration' if you want to google
    class A { unique_ptr<B> b; };
    class B { unique_ptr<A> a; };
...generally classes instantiating each other is a sign that your design needs rearranged, but it has its uses when writing graph types.


Because it doesn't make sense. These types would have infinite size.


You should be able to do that with either references or pointers between classes with a forward declaration. In essence:

  class B;
  class A { B* b;}
  class B { A* a;}


shrugs I still like to code in C++. Beats having to use JS ;)


Well that's faint praise indeed. ;)


I've been spending a few days going through talks from last years cppcon[1]. They're all good, but they've all left me with a strong desire for a strongly opinionated, there-is-no-past-only-the-future introduction to C++14 (and incidentally, C11).

I've added a few of those talks I've watched and liked to a small playlist (with a couple of other talks on programming, unrelated - the relevant talks are prefixed with "cppcon 2015"):

https://www.youtube.com/playlist?list=PLHvt7sld3hmvdDnwHkdU2...

The full cppcon playlist is here: https://www.youtube.com/playlist?list=PLHTh1InhhwT75gykhs7pq...

Of special relevance is the rather excellent talk by Kate Gregory on "Stop Teaching C" (when you're supposed to do an intro course to C++):

"CppCon 2015: Kate Gregory “Stop Teaching C"": https://www.youtube.com/watch?v=YnWhqhNdYyk

(But again, I want an open wiki/live tutorial, along the lines of "How I start", but longer, which goes through all this stuff. We really should make one, both for C++14 and for C11).

CppCon 2015: Herb Sutter "Writing Good C++14... By Default": https://www.youtube.com/watch?v=hEx5DNLWGgA Is also rather uplifting, and:

CppCon 2015: Sean Parent "Better Code: Data Structures": https://www.youtube.com/watch?v=sWgDk-o-6ZE

makes a pretty good case for simple, modern C++ being clear, easy and efficient.

Finally,

CppCon 2015: Phil Nash “Test Driven C++ with Catch”: https://www.youtube.com/watch?v=gdzP3pAC6UI

apart for being a pretty straight forward intro to a simple testing framework, appears to reveal some secrets combining template magic and still get sane compile times (hint: don't recompile more (template) code on every iteration than you need to).

There's a couple of good ones that touch on meta-programming too (Look for the talk on Spirit X3 and Brigand), and there's a nice lightning talk on clang-tidy (magically go from explicit loops to modern foreach, yay!).




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: