4 ms·
There's nothing really fundamental to the changes in C++11 and beyond: There are lots of little tweaks, as well as some deprecations and outright removals. Howe
by atombender 8y ago
There's nothing really fundamental to the changes in C++11 and beyond: There are lots of little tweaks, as well as some deprecations and outright removals. However, there's the prevailing sense in the community that the many tweaks together genuinely change the flavour of the language, at least from the perspective of traditional C++ development.
The combination of "auto" (plus template type inference), ranged for-loops, initializer lists, structured bindings, lambdas and certain new standard library mechanisms (std::unique_ptr, std::variant, std::optional, std::move, etc.) together change the high-level expressiveness of the language, encoding a lot of common patterns and eliminating common, redundant code. For example:
std::vector values = {1, 2, 3};
for (auto v : values) { ... }
New for loops support structured bindings:
for (auto &&[key, value] : mapOfStuff) { ... }
There's a lot of little conveniences, such as the ability to define a default constructor, or accept a initializer list in the constructor:
struct Foo {
Foo(std::initializer_list<int> values) { ... }
}
Foo f = {1, 2, 3};
or indeed named initializers:
struct Person {
string name
}
Person p = {.name = "bob"};
The forthcoming range library in C++20 also finally make lazy sequence iteration functional and composable, e.g. something like (off the top of my head):
getNumbers()
| view::filter([](int a, int b) { return a > b; }
| view::reverse()
| view::take(10);
Another big change that's coming is concepts, which are somewhat similar to Rust traits or Haskell typeclasses: The ability to put compile-time constraints on template arguments. For example, in classical C++, invalid template invocations generate notoriously bad error messages, since templates are only compiled once they have been expanded with their arguments:
template <typename T>
T add100(T v) {
// Compiler will fail on this line:
return v + 100;
}
auto n = add100("hello world");
Concepts will let you constrain T to something that actually supports the operations you need:
template <Incrementable T>
T add100(T v) {
return v + 100;
}
// Compiler fails on this line:
auto n = add100("hello world");
Then there's the contract spec, which adds support for Eiffel-type contracts.
Lastly, C++ designers seem to have thought a lot about safe memory semantics, and so there's a renewed focus on smart pointers (that actually work) together with move semantics and tightening of cop constructor semantics. The end result is that it's generally easier to work with RAII and avoid explicit heap allocation with the "new" keyword.
- TeMPOraL 8y agoWow, thanks for the detailed description! I guess I'll have to think a bit about each new feature from C++11, 14 and 17, and then Google some more, to understand the full implications.
- atombender 8y agoDo let us know if you find any kind of "summary for old C++ devs". I agree that such a document would be super useful.