Modern C++ Workshop
Day 1 - Overview
Agenda
-
Monday, September 5th
- overview
- auto type deduction
-
Tuesday, September 6th
- new class definition features
-
Wednesday, September 7th
- STL containers and algorithms
-
Thursday, September 8th
- memory management and move semantics
-
Friday, September 9th
- concurrency
- exceptions
-
Monday, September 12th
- Q&A and topics you'd like to dig deeper into
Disclaimer
This is a 10000 ft overview. Don't expect to fully grasp everything.
Follow up sessions will repeat everything and drill much further into details.
Some of the material presented is opinionated.
It's really helpful to look at assembly using http://gcc.godbolt.org/
C++11 + 14 + 17
- rethinking c++
- strong backwards compatibility
- catch-up with newer languages
-
many more things you shouldn't do
- even more than before
- some things that were considered best practice before
- much higher developer productivity!
Major new features of modern C++
- auto type deduction
- range-based for loops
- lambda functions
- new STL algorithms and containers
- nullptr and nullptr_t
- move semantics
- memory management library
- allocator traits
- threading and parallelism library
- variadic templates
- decltype
auto type deduction
// typeof(connection)
// is std::shared_ptr<Connection>
auto connection =
std::make_shared<Connection>();
// typeof(sum) is int
auto sum = 3 + 4;
// typeof(ratio) is double
auto ratio = sum / 4.0
range based for loops
auto numbers =
{1,7,8,12,4,9};
for(const auto& n : numbers) {
std::cout
<< n
<< std::endl;
}
lambda functions
std::vector<int> numbers = {1,4,19};
// find the first n > 8 in vector
auto number =
std::find_if(
numbers.begin(),
numbers.end(),
[](const auto& n) {
return n > 8;
});
// remove even numbers
numbers.erase(
std::remove_if(
numbers.begin(),
numbers.end(),
[](const auto& n) {
return n % 2 == 0;
}));
STL Containers
Hash based containers std::unordered_set and std::unordered_map provide average O(1) lookups and inserts.
std::array should replace C-style arrays for most use cases.
std::tuple can contain tuples of arbitrary types
STL Algorithms
Lambdas now can be used in algorithms where applicable.
Numerous new algorithms have been added:
all_of, any_of, none_of, find_if_not, copy_if, copy_n, move, move_backward, shuffle, is_partitioned, partition_copy, partition_point, is_sorted, is_sorted_until,
is_heap, is_heap_until, minmax, minmax_element, is_permutation, iota, uninitialized_copy_n
Containers have new operations like emplace, shrink_to_fit
nullptr and nullptr_t
Gets rid of dangerous ambiguities like the following:
std::string s1( false ); // compiles, calls char* constructor with null
std::string s2( true ); // error
move semantics
New resource management feature serving two purposes:
1. Gain performance by avoiding copies
std::string oneTerabyteString = fillOneTerabyteString();
std::vector<std::string> myStrings;
mystrings.push_back(std::move(oneTerabyteString));
// terabytes of data have not been copied
2. Enforce semantic correctness by permitting resource transfer while forbidding copies
void consumeResource(std::unique_ptr<Resource> resource) {
doSomeThingWith(*resource);
}
// resource is allocated
auto uniqueResource = std::make_unique<Resource>();
consumeResource(std::move(uniqueResource));
// resource is freed in consumeResource
memory management
std::shared_ptr and std::weak_ptr behave like their boost cousins.
std::unique_ptr cannot been copied, but can be transferred via move. This enables safe and performant memory management by restricting ownership to one owner.
allocator traits
std::allocator_traits provide reasonable defaults for most allocator operations and make creating your own allocators viable in a many more situations
threading and parallelism
thread_local keyword enables thread local storage.
std::thread, std::mutex, std::lock_guard, std::atomic offer a similar API to boost
std::promise and std::future offer higher-level syncronization primitives
Thanks!
Questions?
variadic templates
// stolen from facebook::folly
template <typename T, typename... Ts>
size_t hash_combine(const T& t, const Ts&... ts) {
size_t seed = std::hash<T>()(t);
if (sizeof...(ts) == 0) {
return seed;
}
// this is expanded + inlined at compile time
size_t remainder = hash_combine(ts...);
return hash_128_to_64(seed, remainder);
}
struct MyStruct {
int x;
std::string y;
double z;
size_t hash() {
return hash_combine(x, y, z);
}
};
decltype
#include <string>
using namespace std::string_literals;
template <typename T, typename U>
auto sum(T a, U b) -> decltype(a + b) {
return a + b;
}
auto doubleSum = sum(5, 4.3); // 9.3
auto stringSum = sum("hello "s, "world!"s); // "hello world!"
Modern C++ Workshop - Day 1
By Jupp Müller
Modern C++ Workshop - Day 1
- 655