5 ms·
What does the C++20 change in a day-to-day work? I know they added "stuff" (as always) but is there anything that really benefits >80% of all cpp programmers?
by badtension 4y ago
What does the C++20 change in a day-to-day work? I know they added "stuff" (as always) but is there anything that really benefits >80% of all cpp programmers?
- jcelerier 4y agoto me concepts and coroutines really reduce the amount of boilerplate needed. - just the ability of doing if constexpr(requires { T::some_member; }) { ... } to check if a type has a member variable / function / whatever makes code infinitely clearer than the previous mess requiring overloads. - coroutines finally enable to properly abstract the data structures used by a type's implementation, e.g. you don't need to spill out anymore that your type stores stuff in std::vector or std::array or boost::small_vector or std::list etc etc to client code, and they simplify async code very well. for instance with Qt: https://qcoro.dvratil.cz/reference/core/qprocess/#examples https://qcoro.dvratil.cz/reference/core/qprocess/#examples - three-way comparison and automtic generation of comparison / equality function is really great for removing needless boilerplate - void f(auto arg) { ... } instead of template<typename T> void f(T arg) { ... } - foo{.designated = 123, .init = "456" }; (although it was already more or less supported on every relevant compiler for years
- 8n4vidtmkvmk 4y agodesignated initializers are a trap. you can't require certain fields are set... this has been a big pain point for my team. guess we should have used builder pattern or something
- pjmlp 4y agoI would say constructors are what should be used for such kind of compound initializations. C# is going the route of allowing required/optional fields in designated initializers, and from my point of view it is just a mess for what should be a constructor call.
- leni536 4y ago> you can't require certain fields are set There is a way, but it's cursed: https://godbolt.org/z/fzc6WEz5e https://godbolt.org/z/fzc6WEz5e
- ncmncm 4y agoClever. Wrap it in a concept, and it might have legs.
- nyanpasu64 4y agoSadly `if constexpr (requires {})` was not implemented in MSVC until VS2022, which was not even released when I tried using it and backed out because it wouldn't build on MSVC, and is still a new and less-adopted compiler than 2019: https://developercommunity.visualstudio.com/t/requires-clause-in-constexpr-if-doesnt-work/929394 https://developercommunity.visualstudio.com/t/requires-claus...
- ascar 4y agoNot really a C++ expert, but two things I saw in the documentation and that came in useful were the "contains" method of maps and the std::span class for passing around contiguous sequences of objects without worrying about creating copies of vectors.
- tialaramex 4y agoIn principle Modules would be huge, but in practice you can't use them as the compiler you have doesn't implement them yet. C++ 20 gets a format feature that's basically a weaker {fmt} library but as part of the standard library. A string formatting feature with reasonable performance and safety as you might be used to from other modern languages. Concepts is nice, that's basically way to express duck typing, it is often described like you're getting more than duck typing but that's all you actually get - but hey, duck typing is useful, and Concepts should have decent error messages whereas doing the equivalent with SFINAE is a recipe for awful diagnostic output.
- ncmncm 4y agoPlease do not post falsehoods seeking to mislead readers. You have been corrected on this point several times before. In fact, C++ Concepts can be used for early enforcement of compile-time duck typing, just for better error messages. In the Standard library they are commonly used that way, for backward compatibility. But Concepts can also implement named-property matching. It is entirely up to the designer of a library how much of each to present.
- tialaramex 4y ago> You have been corrected on this point several times before. You have repeatedly (across numerous HN threads) insisted that Concepts aren't just duck typing but that doesn't make it so. > But Concepts can also implement named-property matching. That's still just duck typing (and it's awkward to do properly). Contrast with the (eventually abandoned) C++ 0x Concepts, which actually has semantic weight to it. Concept Maps allow C++ 0x Concepts to have some sort of chance in a language that's already in widespread use, because you can adapt an existing type to the Concept using a Map. But C++ 20 Concepts doesn't offer any of that, after about a decade it's just duck typing.
- ncmncm 4y ago
- 4y ago
- kllrnohj 4y agoCompared to a decade ago a bunch of stuff in no particular order: 1) malloc/new & free/delete are now solidly legacy territory of the "unless it's a placement `new`, you're likely doing it wrong". make_unique && make_shared all day long. 2) templates that are understandable by mortals thanks to `if constexpr` instead of SFINAE nightmares. 3) static_asserts 4) lambdas (which is going to get way more useful with https://en.cppreference.com/w/cpp/utility/functional/move_only_function/move_only_function https://en.cppreference.com/w/cpp/utility/functional/move_on... ) 5) std::format 6) attributes like [[nodiscard]] being standard 7) std::move making passing std:vector & similar containers around not being terrifying (this is what also really helps #1 be possible) I'm sure I missed some stuff, but I reach for all of those regularly.
- hedora 4y agoauto
- charcircuit 4y agoWhat makes move_only_functions useful?
- corysama 4y agostd::function is literally an object that can be invoked like a function. As an object, it can contain multiple values. Move-only values are very used for common situations of unique resources that should not be duplicated. But, what if you want to enclose a move-only value in a std::function? Are you simply out of luck and must give up on your dreams? A move-only function lets you get that work done.
- kllrnohj 4y agoMy majority usage of lambdas is for use with work queues (so think Java executor). With the std only the easiest way to build that is a vector of std::function. But then your lambdas can't capture unique_ptrs, even though lambdas themselves have supported move captures for a long long time now. You can do this with std::packaged_task, but that has internal heap allocations for the future. Which if you don't need is just overhead, and not cheap overhead at that.