void foo(int& x) {}
void foo(int&& x) {} // For rvalues only
Moving an object is often cheaper than copying the entire object.
Perfect forwarding: the ability to pass arguments while maintaining their value category.
- T& & -> T&
- T& && -> T&
- T&& & -> T&
- T&& && -> T&&
... accepts zero or more arguments. We can then create an initializer list from a parameter pack to iterate over it.
template<typename... arguments>
void test {
auto list = {arguments...};
for(const auto& e: list) {
cout << e << endl;
}
};
It corresponds to a lightweight array-like container using a braced list.
vector<int> container = {1,2,3,4,5,6}; // Initializer list
Compile time assertions
static_assert(1 == 1); // 1 == 2 wouldn't allow the code to compile
Type is deducted by the compiler according to the initializer. It helps a lot for code readability, especially for fancy types.
auto x = 1;
Unamed function that can return some value. It has a capture list ([] -> nothing, [=] -> by value, [&] -> by reference, [this] -> capture this by reference)
auto increase_function = [](int x) -> int {
return x + 1;
};
Returns the decltype of an expression. Constant value qualifier are maintained
const int a = 1;
decltype(a) b = a; // decltype(a) is const int
Similar to typedef, but are easier to read and are compatible with templates.
using vec_int = std::vector<int>;
Type safe representation of null pointer. It replaces C NULL macro and is of type std::nullptr_t. Implicitly convertible to pointer types.
enum class Test : int {
v1 = 0
v2 = 1
}
auto x = Test::v1;
Universal syntax for all compilers.
class [[nodiscard]] my_class{}; // We should not discard the returned type of a function
Set of expression that could potentially be evaluated by the compiler at compile time. Can be used for variables / functions. There is no guarantee regarding whether or not it will be evaluated at compile time.
constexpr int fib(int x) {
assert(x >= 0);
if(x == 0) return 0;
return fib(x-1) + fib(x-2);
}
Constructors can now call other constructors in the same class using an initializer list.
use the override keyword. If the function doesn't override a parent's virtual function, you an throw a compiler error.
A virtual function can't be overridden from a derived calls.
Elegant and efficient way to provide default initialization of an object.
Elegant and efficient way to provide a deleted implementation of a function.
Syntatic sugar over iterator.
for(const auto& val: container) {
// Do something here
}
C++ 11 introduces a new constructor and a new assignment operator for move semantics.
struct A {
A(A&& other) {} // Move constructor
A& operator=(A&& other) { // Move assignment operator
// Do some stuff here
return *this;
}
}
Converting constructors will convert values of braced list into constructor arguments.
struct A {
A(int) {}
A(int,int) {}
};
A a1 = {0}; // Calls first constructor
A a2 = {0,0}; // Calls second constructor
However if there is a constructor with initializer list, we will use this constructor instead.
struct A {
A(int) {}
A(int,int) {}
A(std::initializer_list<int>) {}
};
A a1 = {0}; // Calls last constructor
A a2 = {0,0}; // Calls last constructor
std::move indicates that its resources can be transferred.
std::unique_ptr<int> p1 = std::make_unique(new int(1));
std::unique_ptr<int> p2 = std::move(p1);
C++11 introduces smart pointers in the stl library
unique pointer isn't copyable but is movable.
weak pointer doesn't modify the reference count of a shared pointer. It can be used to avoid circular dependencies / caching systems.
Pointer should be created with the make_function.
std:::uniqe_ptr<T> ptr; // Unique pointer
std::shared_ptr<T> ptr; // Shared pointer
is a standard way to use threads in c++. It provides instructions to start, stop and synchronize between them.
std::async on the othre size runs the given function either asynchronously or lazily evaluated depending on the std::launch policy. It returns a std::future object.
int foo() { return 0; }
auto future = std::async([std::launch::async | std::launch::deferred], foo);
std::cout << future.get() << std::endl; // Wait for the result
std::forward allow to keep the value category and cv-qualifiers of an argument.
void overloaded(const int& x) { cout << "[lvalue] ";}
void overloaded(int&& x) { cout << "[rvalue] ";}
template <typename T>
void function(T&& x) {
overloaded(x); // Calls first functions
overloaded(std::forward<T>(x)); // Can call both functions
}
Unordered containers are implemented using hashing and therefore have constant-time complexity for search, insertion and deletion. On the other side we don't have ordering.
This library can be used to benchmark code.
std::to_string converts numeric values in string.
Type traits defines compile mechanism for query properties about types
std::is_integral<T>::value;
std::conditional<X, double, float>::type;
Tuples are fixed-sized collection of heterogeneous values. We can access them using std::tie or std::get
auto t = std::make_tuple(1,"coucou", 1.4);
std::cout << std::get<0>(t) << " " << std::get<0>(t) << " " << std::get<0>(t) << std::endl;
std::tie(v1,v2,v3) = t;
This is a simple array build on top of a C-style array. It supports all the common operations.
This keyword is used to create object of type std::reference_wrapper that holds a reference of value
These two functions are used to return begin and end iterator generically and also works with raw arrays.
Compile time gcd with template metaprogramming