* `unique_ptr` as a local variable. Before C++11, I needed to either (a) define a holder class for anything that should be deleted at the end of a scope or (b) delete it manually and pray that there isn't an exception thrown. Now, I can just declare it, and trust the destructor to clean up after me.
* `unique_ptr` as a return value. Previously, if a function returns a pointer, there was no way on knowing who was responsible for calling `delete`. Now, I can clearly indicate intent. `unique_ptr` means that the caller now owns the object, while C-style pointer or reference means that the callee still owns the object.
* With lambda statements, I can call `std::sort` in-place, with the sorting criteria immediately visible. Previously, I would need to define a function elsewhere in the code, obscuring what may be a simple `a.param < b.param`.
* With range-based for loops, I can loop over any container without needing the very long `std::vector<MyClassName>::iterator` declaration.
* `= delete` to remove an automatically generated method, such as copy constructors. Previously, you would declare that method to be private, then never make an implementation of it. `= delete` shows your intent much more clearly.
* `static_assert`, so that you can bail out of templates earlier, and with reasonable error messages.
* Variadic templates. These aren't needed in 99% of cases, but they are incredibly useful when designing libraries.
* `std::thread` No more messing around with different thread libraries depending on which platform you are on.
True, I didn't mention it, because it has its own issues. The move-on-copy semantics of auto_ptr makes it incompatible with std containers, and makes for some rather unexpected behavior.
* `unique_ptr` as a local variable. Before C++11, I needed to either (a) define a holder class for anything that should be deleted at the end of a scope or (b) delete it manually and pray that there isn't an exception thrown. Now, I can just declare it, and trust the destructor to clean up after me.
* `unique_ptr` as a return value. Previously, if a function returns a pointer, there was no way on knowing who was responsible for calling `delete`. Now, I can clearly indicate intent. `unique_ptr` means that the caller now owns the object, while C-style pointer or reference means that the callee still owns the object.
* With lambda statements, I can call `std::sort` in-place, with the sorting criteria immediately visible. Previously, I would need to define a function elsewhere in the code, obscuring what may be a simple `a.param < b.param`.
* With range-based for loops, I can loop over any container without needing the very long `std::vector<MyClassName>::iterator` declaration.
* `= delete` to remove an automatically generated method, such as copy constructors. Previously, you would declare that method to be private, then never make an implementation of it. `= delete` shows your intent much more clearly.
* `static_assert`, so that you can bail out of templates earlier, and with reasonable error messages.
* Variadic templates. These aren't needed in 99% of cases, but they are incredibly useful when designing libraries.
* `std::thread` No more messing around with different thread libraries depending on which platform you are on.