← Back to context

Comment by Arech

9 months ago

> stdlib changes is what most of "modern C++" is about). the last good version was basically C++11.

I can only comment this like: tell me you have no idea about current state of C++ without telling me you have no idea about current state of C++.

Then let's hear some counter examples please. As far as I'm aware the last important language change since C++11 was designated init in C++20, and that's been butchered so much compared to C99 that it is essentially useless for real world code.

  • There a whole bunch of features and fixes that each new version of the standard proclaimed, which severely affected usability, expressibility and convenience of the language. Describing many of them could easily take an hour. I'm sorry, I can only highlight a few of my particular favourites that I regularly use and let you study the rest changes.

    https://en.cppreference.com/w/cpp/14

    - fixed constexpr, which in C++11 was basically unusable

    - great improvements for metaprogramming, which made such gems as `boost::hana` possible, such as variable templates and generic lambdas.

    - function return type deduction

    https://en.cppreference.com/w/cpp/17

    - inline variables finally fixes the biggest pain of developing header-only libraries

    - useful noexcept fix

    - if constexpr + constexpr lambdas

    - structured bindings

    - guaranteed copy elision

    - fold expressions

    I'm at automotive where due to safety requirements we just barely started to work with C++17, so I don't have much practical experience of the standards past it, though I'm aware there are great updates too. Overall - C++11 is as horrible compared to C++17, as C++98 and roughly 03 were compared to ground breaking back then C++11. Personally, when I skim though job vacancies and see they are stuck at C++11, I pass it. Even C++14 makes me very sceptical, even though I used it really a lot. All due to new nice improvements of C++17.

    https://en.cppreference.com/w/cpp/20

    https://en.cppreference.com/w/cpp/23

    • Ok, I'll give you fold expressions and structured bindings as actually important language updates. The rest are mostly just tweaks that plug feature gaps which shouldn't have existed in the first place when the basic feature was introduced in C++11 or earlier.

      IMHO by far most things which the C++ committee accepts as stdlib updates should actually be language changes (like for instance std::tuple, std::variant or std::range). Because as stdlib features those things make C++ code more and more unreadable compared to "proper" syntax sugar (Rust suffers from the exact same problem btw).

      6 replies →

  • A practical example on C++14 & its constexpr+variable templates fixes, and why this was important: a while ago I wrote a wrapper over a compile-time fixed size array that imposed a variable compile-time fixed tensor layout on it. Basically, it turned a linear array into any matrix, or 3D or 4D or whatever -D is needed tensor and allowed to efficiently work with them in compile time already. There was obviously constexpr constuction + constexpr indexing + some constexpr tensor operations. In particular there was a constexpr trace operation for square matrices (a sum of the elements on the main diagonal, if I'm not mistaken). I decided to showcase the power of constexpr to some juniors in the team. For some reason, I thought that since the indexing operation is constexpr, then computing the matrix trace would require a compiler to just take elements of the matrix at precomputed at compile time addresses, which will be seen in the disassembly as memory loads from fixed offsets (without computing these offsets in runtime, since matrix layout is fixed in a compile time and index computation is constexpr operation). So I quickly wrote an example, compiled it with asm output, and looked at it... It was a facepalm moment - I forgot that trace() was also constexpr, so instead of doing any runtime computations at all, the code just had already computed trace value as a constant in a register. How is it not cool? Awesome!

    Such things are extremely valueable as they allow to write much more expressive and easy to understand and maintain code for entities known in a compile time.