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/
// 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
auto numbers =
{1,7,8,12,4,9};
for(const auto& n : numbers) {
std::cout
<< n
<< std::endl;
}
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;
}));
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
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
Gets rid of dangerous ambiguities like the following:
std::string s1( false ); // compiles, calls char* constructor with null
std::string s2( true ); // error
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
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.
std::allocator_traits provide reasonable defaults for most allocator operations and make creating your own allocators viable in a many more situations
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
// 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);
}
};
#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!"