SlideShare uma empresa Scribd logo
1 de 68
Baixar para ler offline
Usability enhancements Type deduction Move semantics Lambda expressions
Modern C++ (C++11/14)
Geeks Anonymes
Damien Gerard
October 19th, 2016
Usability enhancements Type deduction Move semantics Lambda expressions
Introduction
“C++11 feels like a new language.” Bjarne Stroustrup (inventor of C++)
Usability enhancements Type deduction Move semantics Lambda expressions
Labels
11 since C++11
14 since C++14
17 since C++17
R that ain’t for kids
Usability enhancements Type deduction Move semantics Lambda expressions
Range-based for loop
for statement syntax extended to allow for easy iteration over a range of
elements:
int myArray[5] = {1, 2, 3, 4, 5};
for(int x : myArray) {
std::cout << x << std::endl;
}
for(int& x : myArray) {
x *= 2; // double value and save
}
for(auto& x : myArray) { // auto = int
x *= 2;
}
11
Usability enhancements Type deduction Move semantics Lambda expressions
auto
Constant iterator over a vector:
std::vector<int> vec(4,100); // four ints with value 100
for(std::vector<int>::const_iterator it = vec.cbegin();
it != vec.cend(); ++it)
{
std::cout << *it << std::endl;
}
auto for type deduction:
std::vector<int> vec(4,100); // four ints with value 100
for(auto it = vec.cbegin(); it != vec.cend(); ++it) {
std::cout << *it << std::endl;
}
11
Usability enhancements Type deduction Move semantics Lambda expressions
Null pointer literal
Constant 0 had the double role of constant integer and null pointer
constant.
void f(int*);
void f(int);
f(NULL); // calls f(int) or error: ambiguous
If NULL defined as 0, f(NULL) calls f(int). Most programmers would
expect f(int*) because NULL means a null pointer in their mind.
Usability enhancements Type deduction Move semantics Lambda expressions
Null pointer literal
nullptr is a pointer literal of type nullptr_t, which is implicitly
convertible and comparable to any pointer type. It is not implicitly
convertible or comparable to integral types, except for bool.
char* pc = nullptr; // compiles
int* pi = nullptr; // compiles
bool b = nullptr; // compiles, b is false
int i = nullptr; // error
f(nullptr); // calls f(int*), not f(int)
f(nullptr_t) will actually call f(int*) using implicit conversion.
11
Usability enhancements Type deduction Move semantics Lambda expressions
Initializer lists
C++03 inherited the initializer-list feature from C.
struct Widget {
float first;
int second;
};
Widget w1 = {0.43f, 10}; // first=0.43f and second=10
Widget w2[] = {{13.4f, 3}, {43.2f, 29}};
Useful albeit limited to Plain Old Data (POD) structs and classes.
Usability enhancements Type deduction Move semantics Lambda expressions
Uniform initialization
Initializer-lists for all classes, including standard containers.
std::vector<std::string> v = { "Hello", "world" };
std::vector<std::string> v({ "Hello", "world" });
std::vector<std::string> v{ "Hello", "world" };
int val = 5.2; // automatic narrowing
int val{5.2}; // error or warning: type ’double’
// cannot be narrowed to ’int’ in initializer list
// insert an explicit static cast static_cast<int>( )
Widget getWidget() {
return {0.43f, 10}; // no need for explicit type
}
11
Usability enhancements Type deduction Move semantics Lambda expressions
Most vexing parse
struct Widget {
Widget();
};
struct WidgetKeeper {
WidgetKeeper(Widget w);
};
WidgetKeeper wKeeper(Widget()); // most vexing parse
Ambiguous call:
1 new instance of Widget, sent to constructor of WidgetKeeper;
2 function declaration: name“wKeeper”, return type WidgetKeeper,
single (unnamed) parameter which is a function returning type
Widget.
Usability enhancements Type deduction Move semantics Lambda expressions
Most vexing parse
Most developers expect the first, but the C++ standard requires it to be
interpreted as the second.
Workaround in C++03 to ensure the first interpretation:
WidgetKeeper time_keeper( (Widget()) );
C++11’s uniform initialization syntax:
WidgetKeeper time_keeper{Widget{}}; 11
Usability enhancements Type deduction Move semantics Lambda expressions
Returning multiple values
void divide(int dividend, int divisor, int& quotient,
int& remainder)
{
quotient = dividend / divisor;
remainder = dividend % divisor;
}
Or even worse, return quotient through the returned value and
remainder as a reference variable:
int divide(int dividend, int divisor, int& remainder) {
remainder = dividend % divisor;
return dividend / divisor;
}
Usability enhancements Type deduction Move semantics Lambda expressions
Returning multiple values
Or, but rather heavy:
struct divideResult {
int quotient;
int remainder;
};
divideResult divide(int dividend, int divisor) {
return { dividend / divisor, dividend % divisor };
}
divideResult result = divide(10, 3);
std::cout << result.quotient << std::endl;
std::cout << result.remainder << std::endl;
11
Usability enhancements Type deduction Move semantics Lambda expressions
Returning multiple values
std::tuple<int,int> divide(int dividend, int divisor) {
return std::make_tuple(dividend / divisor,
dividend % divisor);
}
int quotient, remainder;
std::tie(quotient, remainder) = divide(10, 3);
C++17’s structured bindings (Clang-4.0 only, as of today):
auto [quotient, remainder] = divide(10, 3);
std::cout << quotient << std::endl;
std::cout << remainder << std::endl;
11
17
Usability enhancements Type deduction Move semantics Lambda expressions
std::unordered *
std::set, map, multiset, multimap associative containers are
implemented as balanced trees. The std::unordered_set,
unordered_map, unordered_multiset, unordered_multimap
alternatives are implemented as hash tables.
Including hash tables was one of the most recurring requests. It was not
adopted in C++03 due to time constraints only. Although hash tables are
less efficient than a balanced tree in the worst case (in the presence of
many collisions), they perform better in many real applications.
11
Usability enhancements Type deduction Move semantics Lambda expressions
emplace, emplace back
emplace and emplace_back can construct an element in-place.
auto employees = std::unordered_map<int, std::string>{};
auto e1 = std::pair<int, std::string>{1, "John Smith"};
employees.insert(e1);
employees.insert(std::make_pair(2, "Mary Jones"));
employees.emplace(3, "James Brown"); // construct in-place
for (const auto& e : employees) {
std::cout << e.first << ": " << e.second << std::endl;
}
11
Usability enhancements Type deduction Move semantics Lambda expressions
In-class initialization
In C++03, in-class initialization on static const members of integral or
enumeration type only.
struct Widget {
static const int a = 7; // compiles
float b = 7.2; // error: not static const integral
const int c = 7; // error: not static
static int d = 7; // error: not const
static const float e = 7.2; // error: not integral
const static int arr[] = { 1, 2, 3 };
// error: must be initialized out of line
};
Usability enhancements Type deduction Move semantics Lambda expressions
In-class initialization
C++11 allows some of them:
struct Widget {
static const int a = 7;
float b = 7.2;
const int c = 7;
static int d = 7; // still fails
static float e = 7.2; // still fails
constexpr static int arr[] = { 1, 2, 3 };
constexpr static std::complex<double> f = { 1, 2 };
};
A non-const static variable still has to be initialized outside the class with
int Widget::d = 7;
float Widget::e = 7.2;
11
Usability enhancements Type deduction Move semantics Lambda expressions
ODR-use
An object is odr-used if its address is taken, or a reference is bound to it.
If a const or constexpr static data member is odr-used, a redefinition (no
initializer permitted) at namespace scope is required.
struct Widget {
static const int n = 1;
static constexpr int m = 4;
};
const int& f(const int& r);
// call f(Widget::n) or f(Widget::m) somewhere
// redefinition at namespace scope required:
const int Widget::n, Widget::m;
C++17 alleviates this constraint for constexpr. A static data member
declared constexpr is implicitly inline and needs not be redeclared at
namespace scope.
R
11
17
Usability enhancements Type deduction Move semantics Lambda expressions
constexpr
Declare something that can be evaluated down to a constant:
constexpr double pi() { return std::atan(1) * 4; }
constexpr double getCircleSurface(double r) {
return pi() * r * r;
}
const double circleSurface = getCircleSurface(0.5);
or
const float oneEighty = degreesToRadians(180.0f);
Since C++14, constexpr functions may have more than one line.
11
14
Usability enhancements Type deduction Move semantics Lambda expressions
Call other constructors
In C++03, other constructors could not be called. Workaround: call a
common member function
class Widget {
int number_;
void construct(int number) { number_ = number; }
public:
Widget(int number) { construct(number); }
Widget() { construct(42); }
};
Usability enhancements Type deduction Move semantics Lambda expressions
Call other constructors
Wrong workaround:
class Widget {
int number_;
public:
Widget(int number) : number_(number) { }
Widget() {
Widget(42);
// this->number_ = 0 or something undefined
}
};
What is wanted but does not compile:
Widget() : Widget(42) { }
Usability enhancements Type deduction Move semantics Lambda expressions
Call other constructors
In C++11 other peer constructors may be called (“delegation”).
class Widget {
int number_;
public:
Widget(int number) : number_(number) { }
Widget() : Widget(42) { }
};
An object is constructed once any constructor finishes execution. Since
multiple constructors are allowed to execute, each delegating constructor
will be executing on a fully constructed object of its own type.
11
Usability enhancements Type deduction Move semantics Lambda expressions
Call or import base class constructors
Call base class constructor:
struct Base {
Base(int number);
};
struct Derived : Base {
Derived(int number) : Base(number) { }
};
Import all base class constructors:
struct Derived : Base {
using Base::Base
};
// can call Derived(42);
11
Usability enhancements Type deduction Move semantics Lambda expressions
Override a base class method
struct Animal {
char* say() const { return "??"; }
};
struct Cow : Animal {
char* say() const { return "moo"; }
};
struct Pig : Animal {
char* say() const { return "oink"; }
};
std::vector<Animal*> animals{new Cow, new Pig};
for(const Animal* a : animals) {
std::cout << a->say() << std::endl;
}
Prints“??” for both the cow and the pig.
Usability enhancements Type deduction Move semantics Lambda expressions
Dynamic polymorphism
struct Animal {
virtual char* say() const { return "??"; }
};
struct Cow : Animal {
virtual char* say() const { return "moo"; }
};
struct Pig : Animal {
virtual char* say() const { return "oink"; }
};
Prints“moo”and“oink”. What if const is forgotten in the Pig’s say()? It
will compile and print“moo”and“??”.
Usability enhancements Type deduction Move semantics Lambda expressions
Typo in derived class
The following code compiles but contains no virtual function overrides.
struct Base {
void f1() const;
virtual void f2() const;
virtual void f3(int x);
}
struct Derived : Base {
void f1() const;
virtual void f2();
virtual void f3(unsigned int x);
}
Usability enhancements Type deduction Move semantics Lambda expressions
overrides
Make explicit that a derived class is expected to override a base class:
struct Derived : Base {
void f1() const override;
virtual void f2() override;
virtual void f3(unsigned int x) override;
}
The compiler will complain about all the overriding-related issues.
11
Usability enhancements Type deduction Move semantics Lambda expressions
final
Prevent overriding:
struct Base {
virtual void f() final;
};
struct Derived : Base {
virtual void f(); // error: ’f’ overrides a ’final’ function
};
Prevent derivation:
struct Base final { };
struct Derived : Base { }; // error: ’Base’ is marked ’final’
This could be achieved in C++03 with private virtual inheritance.
11
Usability enhancements Type deduction Move semantics Lambda expressions
Explicitly deleted functions
struct Widget {
void f(double i);
void f(int) = delete;
};
Widget w;
w.f(3.0); // ok
w.f(3); // error: explicitely deleted
Explicitely deleted special member functions:
struct Widget {
Widget() = default;
Widget(const Widget&) = delete;
Widget& operator=(const Widget&) = delete;
};
11
Usability enhancements Type deduction Move semantics Lambda expressions
Unrestricted unions
In C++03, unions cannot contain any objects that define a
non-trivial constructor or destructor. C++11 lifts some restrictions.
struct Widget {
int x_;
Widget() {}
Widget(int x) : x_(x) {}
};
union U {
double f;
Widget w; // illegal in C++03, legal in C++11
};
U u; // error: call to implicitely deleted default constructor o
// note: default constructor of ’U’ is implicitely deleted
// because field ’w’ has a non-trivial default constructor
11 R
Usability enhancements Type deduction Move semantics Lambda expressions
Unrestricted unions
A constructor for the union must be manually defined:
union U {
double f;
Widget w;
U(int x) : w(x) { }
};
U u(3);
11 R
Usability enhancements Type deduction Move semantics Lambda expressions
Strongly typed enumerations
C++03 enumerations are not type-safe. It allows the comparison between
two enum values of different enumeration types. Type-safe enumeration:
enum class Enum1 {
Val1 = 100,
Val2 // = 101
};
Override the default underlying type:
enum class Enum2 : unsigned long {Val1, Val2};
Other examples:
enum Enum3; // Underlying type cannot be determined (C++03/11)
enum class Enum4; // Underlying type is int (C++11)
11
Usability enhancements Type deduction Move semantics Lambda expressions
Template type deduction for classes
Template class:
template<typename T> // "typename" and "class" are synonymous
class Stack {
std::vector<T> elems_;
public:
void push(const T& elem) { elems_.push_back(elem); }
T top() const { return elems_.back(); }
void pop() { elems_.pop_back(); }
};
Stack<double> myStack; // T = double
Stack<int*> myStack; // T = int*
One Stack code for double and another Stack code for int*.
Usability enhancements Type deduction Move semantics Lambda expressions
Template type deduction for functions
template <typename T>
inline T max(T a, T b) {
return a > b ? a : b;
}
std::cout << max(3.0, 7.2) << std::endl; // T = double
std::cout << max("hello", "world") << std::endl;
struct Widget {
int x_;
Widget(int x) : x_(x) { }
};
Widget w1(3), w2(4);
std::cout << max(w1, w2) << std::endl;
// error: invalid operands to binary expression
Usability enhancements Type deduction Move semantics Lambda expressions
Template partial specialization for loop unrolling
The template may also be a value instead of a class, allowing e.g. for
compile-time loop unrolling, with partial specialization:
template <unsigned int N>
int factorial() {
return N * factorial<N - 1>();
}
template <>
int factorial<0>() {
return 1;
}
std::cout << factorial<4>() << std::endl; // yields 24
Since C++11, the same can be performed with constexpr.
R
11
Usability enhancements Type deduction Move semantics Lambda expressions
auto for variable type deduction
std::vector<int> vec{10, 11, 12, 13};
for(auto it = vec.cbegin(); it != vec.cend(); ++it) {
std::cout << *it << std::endl;
}
11
Usability enhancements Type deduction Move semantics Lambda expressions
decltype for return type deduction
template<typename T, typename U>
SomeType mul(T x, U y) {
return x*y;
}
The return type is“the type of x*y”. How can we write that?
template<typename T, typename U>
decltype(x*y) mul(T x, U y) {
return x*y;
}
It does not compile because x and y are not in scope. We can use a
trailing return type.
11
Usability enhancements Type deduction Move semantics Lambda expressions
decltype for return type deduction
Trailing return type:
template<typename T, typename U>
auto mul(T x, U y) -> decltype(x*y) {
return x*y;
}
When decltype is read, x and y are now known to the compiler. auto is
only meant to tell the compiler that it will find the return type after ->.
auto does not deduce anything.
11
Usability enhancements Type deduction Move semantics Lambda expressions
Generalized return type deduction
Since C++14, auto can deduce the return type of functions:
auto floor(double x) { return static_cast<int>(x); }
Multiple returns are allowed, but the type must be the same:
auto f() {
while(something()) {
if(expr) {
return foo() * 42;
}
}
return bar.baz();
}
14
Usability enhancements Type deduction Move semantics Lambda expressions
Generalized return type deduction
The return type deduction also works for recursive functions, provided the
non-recursive return statement is before the recursive call.
auto f() { return f(); } // error: return type of f is unknown
auto sum(int i) {
if (i == 1)
return i; // return type deduced to int
else
return sum(i-1)+i; // ok to call it now
}
14
Usability enhancements Type deduction Move semantics Lambda expressions
decltype(auto)
auto always deduces a non-reference type (int, double. . . ). auto&
always deduces a reference type (int&, double&. . . ). But auto cannot
conditionnaly see if the return type is a reference.
decltype can, but requires to write an expression in its parentheses.
We can use the best of both worlds with decltype(auto) which can
deduce if the type is a reference.
template<typename T, typename U>
decltype(auto) mul(T x, U y) {
return x*y;
}
14
Usability enhancements Type deduction Move semantics Lambda expressions
Copy-and-swap idiom
class Array {
int* arr_;
unsigned int size_;
public:
Array(unsigned int size = 0) : size_(size),
arr_(size > 0 ? new int[size]() : nullptr) { }
Array(const Array& other) : size_(other.size_),
arr_(other.size_ > 0 ? new int[other.size_] : nullptr)
{
std::copy(other.arr_, other.arr_ + size_, arr_);
}
~Array() { delete[] arr_; }
};
Usability enhancements Type deduction Move semantics Lambda expressions
Copy-and-swap idiom
Na¨ıve implementation of operator=:
Array& operator=(const Array& other) {
if (this != &other) {
delete [] arr_;
arr_ = nullptr;
arrSize_ = other.arrSize_;
arr_ = arrSize_ ? new int[arrSize_] : nullptr;
std::copy(other.arr_, other.arr_ + arrSize_, arr_);
}
return *this;
}
Usability enhancements Type deduction Move semantics Lambda expressions
Copy-and-swap idiom
Issues:
1 code duplication;
2 if(this != &other) mandatory but should not occur;
3 if new[] fails, *this will have been modified (no strong exception
guarantee).
Usability enhancements Type deduction Move semantics Lambda expressions
Copy-and-swap idiom
Successful solution:
friend void swap(Array& first, Array& second) {
using std::swap; // enable ADL
swap(first.size_, second.size_);
swap(first.arr_, second.arr_);
}
Array& operator=(Array other) {
swap( *this, other );
return *this;
}
Array getArray(unsigned int size) { return Array(size); }
Array arr = getArray(4);
Usability enhancements Type deduction Move semantics Lambda expressions
Copy Elisions, Returned Value Optimization
Distinguish parameter and argument:
other is the parameter of the function;
the array returned by getArray(4) is the argument, from which the
parameter other is instanciated.
If the argument is a temporary object which will be destroyed, why make a
copy for other? The argument should become other, thereby avoiding
copy.
Most C++03 compilers could grasp this optimization opportunity
whenever possible and elude the copy.
Guideline: Do not copy the function arguments. Instead, pass them by
value and let the compiler manage the copying.
Usability enhancements Type deduction Move semantics Lambda expressions
Lvalue – Rvalue
C++11 formalized everything:
a temporary object, eligible for copy elision, is an rvalue;
otherwise it is an lvalue.
References:
an integer lvalue-reference is denoted int&;
an integer rvalue-reference is denoted int&&.
11
Usability enhancements Type deduction Move semantics Lambda expressions
Move constructor and move assignment operator
There are two new special member functions.
Move constructor:
Array(Array&& other) : Array() {
swap( *this, other );
}
Move assignment operator:
Array& operator=(Array&& other) {
swap( *this, other );
return *this;
}
11
Usability enhancements Type deduction Move semantics Lambda expressions
Specialize code for lvalue or rvalue
void f(int& param) {
std::cout << "lvalue" << std::endl;
}
void f(int&& param) {
std::cout << "rvalue" << std::endl;
}
int a;
f(a); // calls void f(int&)
f(std::move(a)); // calls void f(int&&)
If you can take a variable’s address, it usually is an lvalue. Otherwise it is
usually an rvalue.
11
Usability enhancements Type deduction Move semantics Lambda expressions
std::move
std::move does not move anything. It casts its parameter as an rvalue.
struct Widget {
Array arr_;
Widget(const Array& param) : arr_(std::move(param)) { }
};
Array arr(3);
Widget w(arr);
compiles but calls the copy constructor of Array instead of the move
constructor. std::move returns a const Array&& which cannot be casted
as a non-const Array&&, but can be casted as a const Array&.
Array(const Array& other); // copy constructor
Array(Array&& other); // move constructor
11
Usability enhancements Type deduction Move semantics Lambda expressions
Distinguish forwarding from rvalue references
A forwarding reference is either an lvalue reference or an rvalue reference.
A forwarding reference has the same syntax as an rvalue reference, namely
“&&”.
Rvalue references examples:
void f(Widget&& param);
Widget&& w1 = Widget();
Forwarding references:
template<typename T>
void f(T&& param);
auto&& w2 = w1;
11
Usability enhancements Type deduction Move semantics Lambda expressions
Distinguish forwarding from rvalue references
Both forwarding references have in common the presence of type
deduction. Rvalue references do not.
template<typename T>
void f(T&& param) {
// Here we can take param’s address
// so param is always an lvalue
}
Widget w;
f(w); // param’s type is lvalue-reference Widget&
// param is lvalue
// T = Widget&
f(std::move(w)); // param’s type is rvalue-reference Widget&&
// param is lvalue
// T = Widget
11
Usability enhancements Type deduction Move semantics Lambda expressions
std::forward
void process(Widget& lValArg); // for lvalues
void process(Widget&& rValArg); // for rvalues
template<typename T>
void logAndProcess(T&& param) {
auto now = std::chrono::system_clock::now();
makeLogEntry("Calling ’process’", now);
process(param); // always calls process(Widget&)
}
Widget w;
logAndProcess(w);
logAndProcess(std::move(w));
Because param is always an lvalue, process(Widget&) is always called.
11
Usability enhancements Type deduction Move semantics Lambda expressions
std::forward
If param’s type is an rvalue-reference, we need to cast the lvalue param as
an rvalue. This is what std::forward does.
std::move always casts as an rvalue; std::forward conditionally casts as
an rvalue.
But how to distinguish? Look at T:
1 if param is an lvalue-reference, T = Widget&;
2 if param is an rvalue-reference, T = Widget.
T must be given to std::forward so it can decide whether to cast its
parameter as an rvalue or not.
process(std::forward<T>(param));
11
Usability enhancements Type deduction Move semantics Lambda expressions
Subtle forwarding and rvalue references
template<typename T>
class vector {
public:
void push_back(T&& x);
};
is not a forwarding reference. Writing std::vector<Widget> v; causes
the template to be instanciated as
class vector<Widget> {
public:
void push_back(Widget&& x);
};
which involves no type deduction.
11 R
Usability enhancements Type deduction Move semantics Lambda expressions
Subtle forwarding and rvalue references
A template forwarding reference must have the form T&&. Hence, the two
following references do not qualify for being forwarding references.
template<typename T>
void f(const T&& param);
template<typename T>
void f(std::vector<T>&& param);
11 R
Usability enhancements Type deduction Move semantics Lambda expressions
Subtle forwarding and rvalue references
The variadic templates of emplace involve type deduction.
template<typename T>
class vector {
public:
template<typename... Args>
void emplace(Args&& args);
};
11 R
Usability enhancements Type deduction Move semantics Lambda expressions
Implementation of std::move in C++11
template<typename T>
typename remove_reference<T>::type&& move(T&& param) {
using ReturnType = typename remove_reference<T>::type&&;
return static_cast<ReturnType>(param);
}
param is a forwarding reference:
if param is an lvalue-reference, T = Widget&;
if param is an rvalue-reference, T = Widget.
Steps:
1 remove_reference<T>::type returns Widget;
2 remove_reference<T>::type&& returns Widget&&;
3 static_cast<Widget&&> casts param as an rvalue.
11 R
Usability enhancements Type deduction Move semantics Lambda expressions
Implementation of std::move in C++14
std::remove_reference_t<T> replaces
typename remove_reference<T>::type.
std::move can elegantly be written as
template<typename T>
decltype(auto) move(T&& param) {
using ReturnType = remove_reference_t<T>&&;
return static_cast<ReturnType>(param);
}
14 R
Usability enhancements Type deduction Move semantics Lambda expressions
Lambda expressions
auto lambda = [](int x, int y) -> int { return x + y; };
std::cout << lambda(2, 3) << std::endl;
Components:
(int x, int y) is the parameters list;
int after -> is the return type;
{...} is the lambda body.
A lambda can be executed upon declaration with trailing“()”:
std::cout
<< [](int x, int y) -> int { return x + y; }(2, 3)
<< std::endl;
11
Usability enhancements Type deduction Move semantics Lambda expressions
std::for each and std::transform
Apply a lambda to each element of an iterator:
void f(std::vector<int>& v) {
std::for_each(v.begin(), v.end(),
[](int p) { std::cout << p << std::endl; });
}
Modify each element with a lambda:
void f(std::vector<double>& v) {
std::transform(v.begin(), v.end(), v.begin(),
[](double d) { return d < 0.00001 ? 0 : d; });
}
C++03 already had std::for_each and std::transform, but
cumbersome functors were necessary since lambdas were not available.
11
Usability enhancements Type deduction Move semantics Lambda expressions
std::for each and std::transform
If the body is not a single return expression, the type has to be explicitely
stated:
void f(std::vector<double>& v) {
std::transform(v.begin(), v.end(), v.begin(),
[](double d) -> double {
if (d < 0.0001)
return 0;
else
return d;
});
}
11
Usability enhancements Type deduction Move semantics Lambda expressions
Lambda captures
[] allows to capture other variables from the scope.
void f(std::vector<double>& v, double epsilon) {
std::transform(v.begin(), v.end(), v.begin(),
[epsilon](double d) -> double {
if (d < epsilon)
return 0;
else
return d;
});
}
We can capture by both reference and value.
11
Usability enhancements Type deduction Move semantics Lambda expressions
Generalized lambda captures
An element of the capture can be initialized with =. This allows renaming
of variables and to capture by moving.
int x = 4;
auto y = [&r = x, x = x+1]() -> int {
r += 2;
return x+2;
}(); // Updates ::x to 6, and initializes y to 7
std::unique_ptr<int> ptr(new int(10));
auto lambda = [value = std::move(ptr)] { return *value; };
std::unique_ptr can be moved but not copied. Capture by move is the
only way to capture a std::unique_ptr.
14
Usability enhancements Type deduction Move semantics Lambda expressions
Generic lambdas
Lambda function parameters may be declared auto.
auto lambda = [](auto x, auto y) { return x + y; };
14
Usability enhancements Type deduction Move semantics Lambda expressions
Improved return type deduction
C++14 allows deduced return types for every function, not only those of
the form return expression.
void f(std::vector<double>& v, double epsilon) {
std::transform(v.begin(), v.end(), v.begin(),
[epsilon](auto d) {
if (d < epsilon)
return 0;
else
return d;
});
}
14
Usability enhancements Type deduction Move semantics Lambda expressions
Remaining modern C++ topics
type traits (std::enable if, std::is pointer. . . );
smart pointers;
threading facilities;
noexcept;
std::function;
std::bind and std::ref;
std::regex;
extern template;
inline namespace. . .

Mais conteúdo relacionado

Mais procurados

C++11 concurrency
C++11 concurrencyC++11 concurrency
C++11 concurrency
xu liwei
 
C++ Overview
C++ OverviewC++ Overview
C++ Overview
kelleyc3
 
Templates in C++
Templates in C++Templates in C++
Templates in C++
Tech_MX
 

Mais procurados (20)

C# Loops
C# LoopsC# Loops
C# Loops
 
Hot C++: Rvalue References And Move Semantics
Hot C++: Rvalue References And Move SemanticsHot C++: Rvalue References And Move Semantics
Hot C++: Rvalue References And Move Semantics
 
Solid C++ by Example
Solid C++ by ExampleSolid C++ by Example
Solid C++ by Example
 
Advanced C - Part 1
Advanced C - Part 1 Advanced C - Part 1
Advanced C - Part 1
 
Trends and future of C++: Evolving a systems language for performance - by Bj...
Trends and future of C++: Evolving a systems language for performance - by Bj...Trends and future of C++: Evolving a systems language for performance - by Bj...
Trends and future of C++: Evolving a systems language for performance - by Bj...
 
C++11 concurrency
C++11 concurrencyC++11 concurrency
C++11 concurrency
 
C++11
C++11C++11
C++11
 
C++ Overview
C++ OverviewC++ Overview
C++ Overview
 
88 c-programs
88 c-programs88 c-programs
88 c-programs
 
Smart Pointers in C++
Smart Pointers in C++Smart Pointers in C++
Smart Pointers in C++
 
Introduction to c programming
Introduction to c programmingIntroduction to c programming
Introduction to c programming
 
Rust: Systems Programming for Everyone
Rust: Systems Programming for EveryoneRust: Systems Programming for Everyone
Rust: Systems Programming for Everyone
 
Linux Ethernet device driver
Linux Ethernet device driverLinux Ethernet device driver
Linux Ethernet device driver
 
Functions in C++
Functions in C++Functions in C++
Functions in C++
 
Functions in c++
Functions in c++Functions in c++
Functions in c++
 
Functions in c
Functions in cFunctions in c
Functions in c
 
Introduction to c++
Introduction to c++Introduction to c++
Introduction to c++
 
Embedded Linux on ARM
Embedded Linux on ARMEmbedded Linux on ARM
Embedded Linux on ARM
 
Templates in C++
Templates in C++Templates in C++
Templates in C++
 
Introduction to Basic C programming 01
Introduction to Basic C programming 01Introduction to Basic C programming 01
Introduction to Basic C programming 01
 

Destaque

Data structures / C++ Program examples
Data structures / C++ Program examplesData structures / C++ Program examples
Data structures / C++ Program examples
Kevin III
 

Destaque (20)

Web I - 05 - HTTP Protocol
Web I - 05 - HTTP ProtocolWeb I - 05 - HTTP Protocol
Web I - 05 - HTTP Protocol
 
C++17 introduction - Meetup @EtixLabs
C++17 introduction - Meetup @EtixLabsC++17 introduction - Meetup @EtixLabs
C++17 introduction - Meetup @EtixLabs
 
TCP/IP
TCP/IPTCP/IP
TCP/IP
 
Bjarne essencegn13
Bjarne essencegn13Bjarne essencegn13
Bjarne essencegn13
 
C++11
C++11C++11
C++11
 
"Http protocol and other stuff" by Bipin Upadhyay
"Http protocol and other stuff" by Bipin Upadhyay"Http protocol and other stuff" by Bipin Upadhyay
"Http protocol and other stuff" by Bipin Upadhyay
 
C++11 & C++14
C++11 & C++14C++11 & C++14
C++11 & C++14
 
HTTP Protocol Basic
HTTP Protocol BasicHTTP Protocol Basic
HTTP Protocol Basic
 
C++17 - the upcoming revolution (Code::Dive 2015)/
C++17 - the upcoming revolution (Code::Dive 2015)/C++17 - the upcoming revolution (Code::Dive 2015)/
C++17 - the upcoming revolution (Code::Dive 2015)/
 
Elements of C++11
Elements of C++11Elements of C++11
Elements of C++11
 
Networking - TCP/IP stack introduction and IPv6
Networking - TCP/IP stack introduction and IPv6Networking - TCP/IP stack introduction and IPv6
Networking - TCP/IP stack introduction and IPv6
 
Database connectivity to sql server asp.net
Database connectivity to sql server asp.netDatabase connectivity to sql server asp.net
Database connectivity to sql server asp.net
 
C++11 Idioms @ Silicon Valley Code Camp 2012
C++11 Idioms @ Silicon Valley Code Camp 2012 C++11 Idioms @ Silicon Valley Code Camp 2012
C++11 Idioms @ Silicon Valley Code Camp 2012
 
C++14 Overview
C++14 OverviewC++14 Overview
C++14 Overview
 
C++ 11 Style : A Touch of Class
C++ 11 Style : A Touch of ClassC++ 11 Style : A Touch of Class
C++ 11 Style : A Touch of Class
 
C# Tutorial MSM_Murach chapter-17-slides
C# Tutorial MSM_Murach chapter-17-slidesC# Tutorial MSM_Murach chapter-17-slides
C# Tutorial MSM_Murach chapter-17-slides
 
C++11 smart pointers
C++11 smart pointersC++11 smart pointers
C++11 smart pointers
 
Data structures / C++ Program examples
Data structures / C++ Program examplesData structures / C++ Program examples
Data structures / C++ Program examples
 
Cpp17 and Beyond
Cpp17 and BeyondCpp17 and Beyond
Cpp17 and Beyond
 
HTTPS: What, Why and How (SmashingConf Freiburg, Sep 2015)
HTTPS: What, Why and How (SmashingConf Freiburg, Sep 2015)HTTPS: What, Why and How (SmashingConf Freiburg, Sep 2015)
HTTPS: What, Why and How (SmashingConf Freiburg, Sep 2015)
 

Semelhante a Modern c++ (C++ 11/14)

C++11: Feel the New Language
C++11: Feel the New LanguageC++11: Feel the New Language
C++11: Feel the New Language
mspline
 
Ch2 introduction to c
Ch2 introduction to cCh2 introduction to c
Ch2 introduction to c
Hattori Sidek
 
C programming session 01
C programming session 01C programming session 01
C programming session 01
Dushmanta Nath
 
C++ Advanced
C++ AdvancedC++ Advanced
C++ Advanced
Vivek Das
 
Functions And Header Files In C++ | Bjarne stroustrup
Functions And Header Files In C++ | Bjarne stroustrupFunctions And Header Files In C++ | Bjarne stroustrup
Functions And Header Files In C++ | Bjarne stroustrup
SyedHaroonShah4
 
Cs2312 OOPS LAB MANUAL
Cs2312 OOPS LAB MANUALCs2312 OOPS LAB MANUAL
Cs2312 OOPS LAB MANUAL
Prabhu D
 

Semelhante a Modern c++ (C++ 11/14) (20)

Gentle introduction to modern C++
Gentle introduction to modern C++Gentle introduction to modern C++
Gentle introduction to modern C++
 
C++11: Feel the New Language
C++11: Feel the New LanguageC++11: Feel the New Language
C++11: Feel the New Language
 
Oh Crap, I Forgot (Or Never Learned) C! [CodeMash 2010]
Oh Crap, I Forgot (Or Never Learned) C! [CodeMash 2010]Oh Crap, I Forgot (Or Never Learned) C! [CodeMash 2010]
Oh Crap, I Forgot (Or Never Learned) C! [CodeMash 2010]
 
Object oriented programming system with C++
Object oriented programming system with C++Object oriented programming system with C++
Object oriented programming system with C++
 
Ppt of c vs c#
Ppt of c vs c#Ppt of c vs c#
Ppt of c vs c#
 
Ch2 introduction to c
Ch2 introduction to cCh2 introduction to c
Ch2 introduction to c
 
C programming session 01
C programming session 01C programming session 01
C programming session 01
 
C++ Advanced
C++ AdvancedC++ Advanced
C++ Advanced
 
Functions And Header Files In C++ | Bjarne stroustrup
Functions And Header Files In C++ | Bjarne stroustrupFunctions And Header Files In C++ | Bjarne stroustrup
Functions And Header Files In C++ | Bjarne stroustrup
 
C++ language
C++ languageC++ language
C++ language
 
Gude for C++11 in Apache Traffic Server
Gude for C++11 in Apache Traffic ServerGude for C++11 in Apache Traffic Server
Gude for C++11 in Apache Traffic Server
 
C++ Overview PPT
C++ Overview PPTC++ Overview PPT
C++ Overview PPT
 
C++
C++C++
C++
 
Introduction to c++
Introduction to c++Introduction to c++
Introduction to c++
 
C++ tutorials
C++ tutorialsC++ tutorials
C++ tutorials
 
unit 1 (1).pptx
unit 1 (1).pptxunit 1 (1).pptx
unit 1 (1).pptx
 
Cs2312 OOPS LAB MANUAL
Cs2312 OOPS LAB MANUALCs2312 OOPS LAB MANUAL
Cs2312 OOPS LAB MANUAL
 
The Style of C++ 11
The Style of C++ 11The Style of C++ 11
The Style of C++ 11
 
1183 c-interview-questions-and-answers
1183 c-interview-questions-and-answers1183 c-interview-questions-and-answers
1183 c-interview-questions-and-answers
 
Functions in C++
Functions in C++Functions in C++
Functions in C++
 

Mais de Geeks Anonymes

Mais de Geeks Anonymes (20)

Programmer sous Unreal Engine
Programmer sous Unreal EngineProgrammer sous Unreal Engine
Programmer sous Unreal Engine
 
Implémentation efficace et durable de processus métiers complexes
Implémentation efficace et durable de processus métiers complexesImplémentation efficace et durable de processus métiers complexes
Implémentation efficace et durable de processus métiers complexes
 
Managing Open Source Licenses (Geeks Anonymes)
Managing Open Source Licenses (Geeks Anonymes)Managing Open Source Licenses (Geeks Anonymes)
Managing Open Source Licenses (Geeks Anonymes)
 
Reprendre le contrôle de ses données
Reprendre le contrôle de ses donnéesReprendre le contrôle de ses données
Reprendre le contrôle de ses données
 
Geeks Anonymes - Le langage Go
Geeks Anonymes - Le langage GoGeeks Anonymes - Le langage Go
Geeks Anonymes - Le langage Go
 
Le rôle du testeur et le Blackbox testing
Le rôle du testeur et le Blackbox testingLe rôle du testeur et le Blackbox testing
Le rôle du testeur et le Blackbox testing
 
Kubernetes
KubernetesKubernetes
Kubernetes
 
Vulnérabilités au cœur des applications Web, menaces et contre-mesures
 Vulnérabilités au cœur des applications Web, menaces et contre-mesures Vulnérabilités au cœur des applications Web, menaces et contre-mesures
Vulnérabilités au cœur des applications Web, menaces et contre-mesures
 
191121 philippe teuwen cryptographie et attaques materielles
191121 philippe teuwen cryptographie et attaques materielles191121 philippe teuwen cryptographie et attaques materielles
191121 philippe teuwen cryptographie et attaques materielles
 
"Surfez couverts !" - Conseils de Cyber securité
"Surfez couverts !" - Conseils de Cyber securité "Surfez couverts !" - Conseils de Cyber securité
"Surfez couverts !" - Conseils de Cyber securité
 
Introduction au développement mobile - développer une application iOS et Andr...
Introduction au développement mobile - développer une application iOS et Andr...Introduction au développement mobile - développer une application iOS et Andr...
Introduction au développement mobile - développer une application iOS et Andr...
 
Le langage rust
Le langage rustLe langage rust
Le langage rust
 
Test your code
Test your codeTest your code
Test your code
 
Intelligence artificielle et propriété intellectuelle
Intelligence artificielle et propriété intellectuelleIntelligence artificielle et propriété intellectuelle
Intelligence artificielle et propriété intellectuelle
 
Pour une histoire plophonique du jeu video
Pour une histoire plophonique du jeu videoPour une histoire plophonique du jeu video
Pour une histoire plophonique du jeu video
 
Become Rick and famous, thanks to Open Source
Become Rick and famous, thanks to Open SourceBecome Rick and famous, thanks to Open Source
Become Rick and famous, thanks to Open Source
 
Reconnaissance vocale et création artistique
Reconnaissance vocale et création artistiqueReconnaissance vocale et création artistique
Reconnaissance vocale et création artistique
 
Natural Language Processing
Natural Language ProcessingNatural Language Processing
Natural Language Processing
 
Sécurité, GDPR : vos données ont de la valeur
Sécurité, GDPR : vos données ont de la valeur Sécurité, GDPR : vos données ont de la valeur
Sécurité, GDPR : vos données ont de la valeur
 
Modern sql
Modern sqlModern sql
Modern sql
 

Último

%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
masabamasaba
 
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
masabamasaba
 
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
masabamasaba
 
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
masabamasaba
 

Último (20)

W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
 
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
 
8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial Goals
 
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdfPayment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
 
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
 
WSO2CON2024 - It's time to go Platformless
WSO2CON2024 - It's time to go PlatformlessWSO2CON2024 - It's time to go Platformless
WSO2CON2024 - It's time to go Platformless
 
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
 
Announcing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK SoftwareAnnouncing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK Software
 
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park %in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
 
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
 
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
 
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
 
%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand
 
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
 
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
 
Introducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) SolutionIntroducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) Solution
 

Modern c++ (C++ 11/14)

  • 1. Usability enhancements Type deduction Move semantics Lambda expressions Modern C++ (C++11/14) Geeks Anonymes Damien Gerard October 19th, 2016
  • 2. Usability enhancements Type deduction Move semantics Lambda expressions Introduction “C++11 feels like a new language.” Bjarne Stroustrup (inventor of C++)
  • 3. Usability enhancements Type deduction Move semantics Lambda expressions Labels 11 since C++11 14 since C++14 17 since C++17 R that ain’t for kids
  • 4. Usability enhancements Type deduction Move semantics Lambda expressions Range-based for loop for statement syntax extended to allow for easy iteration over a range of elements: int myArray[5] = {1, 2, 3, 4, 5}; for(int x : myArray) { std::cout << x << std::endl; } for(int& x : myArray) { x *= 2; // double value and save } for(auto& x : myArray) { // auto = int x *= 2; } 11
  • 5. Usability enhancements Type deduction Move semantics Lambda expressions auto Constant iterator over a vector: std::vector<int> vec(4,100); // four ints with value 100 for(std::vector<int>::const_iterator it = vec.cbegin(); it != vec.cend(); ++it) { std::cout << *it << std::endl; } auto for type deduction: std::vector<int> vec(4,100); // four ints with value 100 for(auto it = vec.cbegin(); it != vec.cend(); ++it) { std::cout << *it << std::endl; } 11
  • 6. Usability enhancements Type deduction Move semantics Lambda expressions Null pointer literal Constant 0 had the double role of constant integer and null pointer constant. void f(int*); void f(int); f(NULL); // calls f(int) or error: ambiguous If NULL defined as 0, f(NULL) calls f(int). Most programmers would expect f(int*) because NULL means a null pointer in their mind.
  • 7. Usability enhancements Type deduction Move semantics Lambda expressions Null pointer literal nullptr is a pointer literal of type nullptr_t, which is implicitly convertible and comparable to any pointer type. It is not implicitly convertible or comparable to integral types, except for bool. char* pc = nullptr; // compiles int* pi = nullptr; // compiles bool b = nullptr; // compiles, b is false int i = nullptr; // error f(nullptr); // calls f(int*), not f(int) f(nullptr_t) will actually call f(int*) using implicit conversion. 11
  • 8. Usability enhancements Type deduction Move semantics Lambda expressions Initializer lists C++03 inherited the initializer-list feature from C. struct Widget { float first; int second; }; Widget w1 = {0.43f, 10}; // first=0.43f and second=10 Widget w2[] = {{13.4f, 3}, {43.2f, 29}}; Useful albeit limited to Plain Old Data (POD) structs and classes.
  • 9. Usability enhancements Type deduction Move semantics Lambda expressions Uniform initialization Initializer-lists for all classes, including standard containers. std::vector<std::string> v = { "Hello", "world" }; std::vector<std::string> v({ "Hello", "world" }); std::vector<std::string> v{ "Hello", "world" }; int val = 5.2; // automatic narrowing int val{5.2}; // error or warning: type ’double’ // cannot be narrowed to ’int’ in initializer list // insert an explicit static cast static_cast<int>( ) Widget getWidget() { return {0.43f, 10}; // no need for explicit type } 11
  • 10. Usability enhancements Type deduction Move semantics Lambda expressions Most vexing parse struct Widget { Widget(); }; struct WidgetKeeper { WidgetKeeper(Widget w); }; WidgetKeeper wKeeper(Widget()); // most vexing parse Ambiguous call: 1 new instance of Widget, sent to constructor of WidgetKeeper; 2 function declaration: name“wKeeper”, return type WidgetKeeper, single (unnamed) parameter which is a function returning type Widget.
  • 11. Usability enhancements Type deduction Move semantics Lambda expressions Most vexing parse Most developers expect the first, but the C++ standard requires it to be interpreted as the second. Workaround in C++03 to ensure the first interpretation: WidgetKeeper time_keeper( (Widget()) ); C++11’s uniform initialization syntax: WidgetKeeper time_keeper{Widget{}}; 11
  • 12. Usability enhancements Type deduction Move semantics Lambda expressions Returning multiple values void divide(int dividend, int divisor, int& quotient, int& remainder) { quotient = dividend / divisor; remainder = dividend % divisor; } Or even worse, return quotient through the returned value and remainder as a reference variable: int divide(int dividend, int divisor, int& remainder) { remainder = dividend % divisor; return dividend / divisor; }
  • 13. Usability enhancements Type deduction Move semantics Lambda expressions Returning multiple values Or, but rather heavy: struct divideResult { int quotient; int remainder; }; divideResult divide(int dividend, int divisor) { return { dividend / divisor, dividend % divisor }; } divideResult result = divide(10, 3); std::cout << result.quotient << std::endl; std::cout << result.remainder << std::endl; 11
  • 14. Usability enhancements Type deduction Move semantics Lambda expressions Returning multiple values std::tuple<int,int> divide(int dividend, int divisor) { return std::make_tuple(dividend / divisor, dividend % divisor); } int quotient, remainder; std::tie(quotient, remainder) = divide(10, 3); C++17’s structured bindings (Clang-4.0 only, as of today): auto [quotient, remainder] = divide(10, 3); std::cout << quotient << std::endl; std::cout << remainder << std::endl; 11 17
  • 15. Usability enhancements Type deduction Move semantics Lambda expressions std::unordered * std::set, map, multiset, multimap associative containers are implemented as balanced trees. The std::unordered_set, unordered_map, unordered_multiset, unordered_multimap alternatives are implemented as hash tables. Including hash tables was one of the most recurring requests. It was not adopted in C++03 due to time constraints only. Although hash tables are less efficient than a balanced tree in the worst case (in the presence of many collisions), they perform better in many real applications. 11
  • 16. Usability enhancements Type deduction Move semantics Lambda expressions emplace, emplace back emplace and emplace_back can construct an element in-place. auto employees = std::unordered_map<int, std::string>{}; auto e1 = std::pair<int, std::string>{1, "John Smith"}; employees.insert(e1); employees.insert(std::make_pair(2, "Mary Jones")); employees.emplace(3, "James Brown"); // construct in-place for (const auto& e : employees) { std::cout << e.first << ": " << e.second << std::endl; } 11
  • 17. Usability enhancements Type deduction Move semantics Lambda expressions In-class initialization In C++03, in-class initialization on static const members of integral or enumeration type only. struct Widget { static const int a = 7; // compiles float b = 7.2; // error: not static const integral const int c = 7; // error: not static static int d = 7; // error: not const static const float e = 7.2; // error: not integral const static int arr[] = { 1, 2, 3 }; // error: must be initialized out of line };
  • 18. Usability enhancements Type deduction Move semantics Lambda expressions In-class initialization C++11 allows some of them: struct Widget { static const int a = 7; float b = 7.2; const int c = 7; static int d = 7; // still fails static float e = 7.2; // still fails constexpr static int arr[] = { 1, 2, 3 }; constexpr static std::complex<double> f = { 1, 2 }; }; A non-const static variable still has to be initialized outside the class with int Widget::d = 7; float Widget::e = 7.2; 11
  • 19. Usability enhancements Type deduction Move semantics Lambda expressions ODR-use An object is odr-used if its address is taken, or a reference is bound to it. If a const or constexpr static data member is odr-used, a redefinition (no initializer permitted) at namespace scope is required. struct Widget { static const int n = 1; static constexpr int m = 4; }; const int& f(const int& r); // call f(Widget::n) or f(Widget::m) somewhere // redefinition at namespace scope required: const int Widget::n, Widget::m; C++17 alleviates this constraint for constexpr. A static data member declared constexpr is implicitly inline and needs not be redeclared at namespace scope. R 11 17
  • 20. Usability enhancements Type deduction Move semantics Lambda expressions constexpr Declare something that can be evaluated down to a constant: constexpr double pi() { return std::atan(1) * 4; } constexpr double getCircleSurface(double r) { return pi() * r * r; } const double circleSurface = getCircleSurface(0.5); or const float oneEighty = degreesToRadians(180.0f); Since C++14, constexpr functions may have more than one line. 11 14
  • 21. Usability enhancements Type deduction Move semantics Lambda expressions Call other constructors In C++03, other constructors could not be called. Workaround: call a common member function class Widget { int number_; void construct(int number) { number_ = number; } public: Widget(int number) { construct(number); } Widget() { construct(42); } };
  • 22. Usability enhancements Type deduction Move semantics Lambda expressions Call other constructors Wrong workaround: class Widget { int number_; public: Widget(int number) : number_(number) { } Widget() { Widget(42); // this->number_ = 0 or something undefined } }; What is wanted but does not compile: Widget() : Widget(42) { }
  • 23. Usability enhancements Type deduction Move semantics Lambda expressions Call other constructors In C++11 other peer constructors may be called (“delegation”). class Widget { int number_; public: Widget(int number) : number_(number) { } Widget() : Widget(42) { } }; An object is constructed once any constructor finishes execution. Since multiple constructors are allowed to execute, each delegating constructor will be executing on a fully constructed object of its own type. 11
  • 24. Usability enhancements Type deduction Move semantics Lambda expressions Call or import base class constructors Call base class constructor: struct Base { Base(int number); }; struct Derived : Base { Derived(int number) : Base(number) { } }; Import all base class constructors: struct Derived : Base { using Base::Base }; // can call Derived(42); 11
  • 25. Usability enhancements Type deduction Move semantics Lambda expressions Override a base class method struct Animal { char* say() const { return "??"; } }; struct Cow : Animal { char* say() const { return "moo"; } }; struct Pig : Animal { char* say() const { return "oink"; } }; std::vector<Animal*> animals{new Cow, new Pig}; for(const Animal* a : animals) { std::cout << a->say() << std::endl; } Prints“??” for both the cow and the pig.
  • 26. Usability enhancements Type deduction Move semantics Lambda expressions Dynamic polymorphism struct Animal { virtual char* say() const { return "??"; } }; struct Cow : Animal { virtual char* say() const { return "moo"; } }; struct Pig : Animal { virtual char* say() const { return "oink"; } }; Prints“moo”and“oink”. What if const is forgotten in the Pig’s say()? It will compile and print“moo”and“??”.
  • 27. Usability enhancements Type deduction Move semantics Lambda expressions Typo in derived class The following code compiles but contains no virtual function overrides. struct Base { void f1() const; virtual void f2() const; virtual void f3(int x); } struct Derived : Base { void f1() const; virtual void f2(); virtual void f3(unsigned int x); }
  • 28. Usability enhancements Type deduction Move semantics Lambda expressions overrides Make explicit that a derived class is expected to override a base class: struct Derived : Base { void f1() const override; virtual void f2() override; virtual void f3(unsigned int x) override; } The compiler will complain about all the overriding-related issues. 11
  • 29. Usability enhancements Type deduction Move semantics Lambda expressions final Prevent overriding: struct Base { virtual void f() final; }; struct Derived : Base { virtual void f(); // error: ’f’ overrides a ’final’ function }; Prevent derivation: struct Base final { }; struct Derived : Base { }; // error: ’Base’ is marked ’final’ This could be achieved in C++03 with private virtual inheritance. 11
  • 30. Usability enhancements Type deduction Move semantics Lambda expressions Explicitly deleted functions struct Widget { void f(double i); void f(int) = delete; }; Widget w; w.f(3.0); // ok w.f(3); // error: explicitely deleted Explicitely deleted special member functions: struct Widget { Widget() = default; Widget(const Widget&) = delete; Widget& operator=(const Widget&) = delete; }; 11
  • 31. Usability enhancements Type deduction Move semantics Lambda expressions Unrestricted unions In C++03, unions cannot contain any objects that define a non-trivial constructor or destructor. C++11 lifts some restrictions. struct Widget { int x_; Widget() {} Widget(int x) : x_(x) {} }; union U { double f; Widget w; // illegal in C++03, legal in C++11 }; U u; // error: call to implicitely deleted default constructor o // note: default constructor of ’U’ is implicitely deleted // because field ’w’ has a non-trivial default constructor 11 R
  • 32. Usability enhancements Type deduction Move semantics Lambda expressions Unrestricted unions A constructor for the union must be manually defined: union U { double f; Widget w; U(int x) : w(x) { } }; U u(3); 11 R
  • 33. Usability enhancements Type deduction Move semantics Lambda expressions Strongly typed enumerations C++03 enumerations are not type-safe. It allows the comparison between two enum values of different enumeration types. Type-safe enumeration: enum class Enum1 { Val1 = 100, Val2 // = 101 }; Override the default underlying type: enum class Enum2 : unsigned long {Val1, Val2}; Other examples: enum Enum3; // Underlying type cannot be determined (C++03/11) enum class Enum4; // Underlying type is int (C++11) 11
  • 34. Usability enhancements Type deduction Move semantics Lambda expressions Template type deduction for classes Template class: template<typename T> // "typename" and "class" are synonymous class Stack { std::vector<T> elems_; public: void push(const T& elem) { elems_.push_back(elem); } T top() const { return elems_.back(); } void pop() { elems_.pop_back(); } }; Stack<double> myStack; // T = double Stack<int*> myStack; // T = int* One Stack code for double and another Stack code for int*.
  • 35. Usability enhancements Type deduction Move semantics Lambda expressions Template type deduction for functions template <typename T> inline T max(T a, T b) { return a > b ? a : b; } std::cout << max(3.0, 7.2) << std::endl; // T = double std::cout << max("hello", "world") << std::endl; struct Widget { int x_; Widget(int x) : x_(x) { } }; Widget w1(3), w2(4); std::cout << max(w1, w2) << std::endl; // error: invalid operands to binary expression
  • 36. Usability enhancements Type deduction Move semantics Lambda expressions Template partial specialization for loop unrolling The template may also be a value instead of a class, allowing e.g. for compile-time loop unrolling, with partial specialization: template <unsigned int N> int factorial() { return N * factorial<N - 1>(); } template <> int factorial<0>() { return 1; } std::cout << factorial<4>() << std::endl; // yields 24 Since C++11, the same can be performed with constexpr. R 11
  • 37. Usability enhancements Type deduction Move semantics Lambda expressions auto for variable type deduction std::vector<int> vec{10, 11, 12, 13}; for(auto it = vec.cbegin(); it != vec.cend(); ++it) { std::cout << *it << std::endl; } 11
  • 38. Usability enhancements Type deduction Move semantics Lambda expressions decltype for return type deduction template<typename T, typename U> SomeType mul(T x, U y) { return x*y; } The return type is“the type of x*y”. How can we write that? template<typename T, typename U> decltype(x*y) mul(T x, U y) { return x*y; } It does not compile because x and y are not in scope. We can use a trailing return type. 11
  • 39. Usability enhancements Type deduction Move semantics Lambda expressions decltype for return type deduction Trailing return type: template<typename T, typename U> auto mul(T x, U y) -> decltype(x*y) { return x*y; } When decltype is read, x and y are now known to the compiler. auto is only meant to tell the compiler that it will find the return type after ->. auto does not deduce anything. 11
  • 40. Usability enhancements Type deduction Move semantics Lambda expressions Generalized return type deduction Since C++14, auto can deduce the return type of functions: auto floor(double x) { return static_cast<int>(x); } Multiple returns are allowed, but the type must be the same: auto f() { while(something()) { if(expr) { return foo() * 42; } } return bar.baz(); } 14
  • 41. Usability enhancements Type deduction Move semantics Lambda expressions Generalized return type deduction The return type deduction also works for recursive functions, provided the non-recursive return statement is before the recursive call. auto f() { return f(); } // error: return type of f is unknown auto sum(int i) { if (i == 1) return i; // return type deduced to int else return sum(i-1)+i; // ok to call it now } 14
  • 42. Usability enhancements Type deduction Move semantics Lambda expressions decltype(auto) auto always deduces a non-reference type (int, double. . . ). auto& always deduces a reference type (int&, double&. . . ). But auto cannot conditionnaly see if the return type is a reference. decltype can, but requires to write an expression in its parentheses. We can use the best of both worlds with decltype(auto) which can deduce if the type is a reference. template<typename T, typename U> decltype(auto) mul(T x, U y) { return x*y; } 14
  • 43. Usability enhancements Type deduction Move semantics Lambda expressions Copy-and-swap idiom class Array { int* arr_; unsigned int size_; public: Array(unsigned int size = 0) : size_(size), arr_(size > 0 ? new int[size]() : nullptr) { } Array(const Array& other) : size_(other.size_), arr_(other.size_ > 0 ? new int[other.size_] : nullptr) { std::copy(other.arr_, other.arr_ + size_, arr_); } ~Array() { delete[] arr_; } };
  • 44. Usability enhancements Type deduction Move semantics Lambda expressions Copy-and-swap idiom Na¨ıve implementation of operator=: Array& operator=(const Array& other) { if (this != &other) { delete [] arr_; arr_ = nullptr; arrSize_ = other.arrSize_; arr_ = arrSize_ ? new int[arrSize_] : nullptr; std::copy(other.arr_, other.arr_ + arrSize_, arr_); } return *this; }
  • 45. Usability enhancements Type deduction Move semantics Lambda expressions Copy-and-swap idiom Issues: 1 code duplication; 2 if(this != &other) mandatory but should not occur; 3 if new[] fails, *this will have been modified (no strong exception guarantee).
  • 46. Usability enhancements Type deduction Move semantics Lambda expressions Copy-and-swap idiom Successful solution: friend void swap(Array& first, Array& second) { using std::swap; // enable ADL swap(first.size_, second.size_); swap(first.arr_, second.arr_); } Array& operator=(Array other) { swap( *this, other ); return *this; } Array getArray(unsigned int size) { return Array(size); } Array arr = getArray(4);
  • 47. Usability enhancements Type deduction Move semantics Lambda expressions Copy Elisions, Returned Value Optimization Distinguish parameter and argument: other is the parameter of the function; the array returned by getArray(4) is the argument, from which the parameter other is instanciated. If the argument is a temporary object which will be destroyed, why make a copy for other? The argument should become other, thereby avoiding copy. Most C++03 compilers could grasp this optimization opportunity whenever possible and elude the copy. Guideline: Do not copy the function arguments. Instead, pass them by value and let the compiler manage the copying.
  • 48. Usability enhancements Type deduction Move semantics Lambda expressions Lvalue – Rvalue C++11 formalized everything: a temporary object, eligible for copy elision, is an rvalue; otherwise it is an lvalue. References: an integer lvalue-reference is denoted int&; an integer rvalue-reference is denoted int&&. 11
  • 49. Usability enhancements Type deduction Move semantics Lambda expressions Move constructor and move assignment operator There are two new special member functions. Move constructor: Array(Array&& other) : Array() { swap( *this, other ); } Move assignment operator: Array& operator=(Array&& other) { swap( *this, other ); return *this; } 11
  • 50. Usability enhancements Type deduction Move semantics Lambda expressions Specialize code for lvalue or rvalue void f(int& param) { std::cout << "lvalue" << std::endl; } void f(int&& param) { std::cout << "rvalue" << std::endl; } int a; f(a); // calls void f(int&) f(std::move(a)); // calls void f(int&&) If you can take a variable’s address, it usually is an lvalue. Otherwise it is usually an rvalue. 11
  • 51. Usability enhancements Type deduction Move semantics Lambda expressions std::move std::move does not move anything. It casts its parameter as an rvalue. struct Widget { Array arr_; Widget(const Array& param) : arr_(std::move(param)) { } }; Array arr(3); Widget w(arr); compiles but calls the copy constructor of Array instead of the move constructor. std::move returns a const Array&& which cannot be casted as a non-const Array&&, but can be casted as a const Array&. Array(const Array& other); // copy constructor Array(Array&& other); // move constructor 11
  • 52. Usability enhancements Type deduction Move semantics Lambda expressions Distinguish forwarding from rvalue references A forwarding reference is either an lvalue reference or an rvalue reference. A forwarding reference has the same syntax as an rvalue reference, namely “&&”. Rvalue references examples: void f(Widget&& param); Widget&& w1 = Widget(); Forwarding references: template<typename T> void f(T&& param); auto&& w2 = w1; 11
  • 53. Usability enhancements Type deduction Move semantics Lambda expressions Distinguish forwarding from rvalue references Both forwarding references have in common the presence of type deduction. Rvalue references do not. template<typename T> void f(T&& param) { // Here we can take param’s address // so param is always an lvalue } Widget w; f(w); // param’s type is lvalue-reference Widget& // param is lvalue // T = Widget& f(std::move(w)); // param’s type is rvalue-reference Widget&& // param is lvalue // T = Widget 11
  • 54. Usability enhancements Type deduction Move semantics Lambda expressions std::forward void process(Widget& lValArg); // for lvalues void process(Widget&& rValArg); // for rvalues template<typename T> void logAndProcess(T&& param) { auto now = std::chrono::system_clock::now(); makeLogEntry("Calling ’process’", now); process(param); // always calls process(Widget&) } Widget w; logAndProcess(w); logAndProcess(std::move(w)); Because param is always an lvalue, process(Widget&) is always called. 11
  • 55. Usability enhancements Type deduction Move semantics Lambda expressions std::forward If param’s type is an rvalue-reference, we need to cast the lvalue param as an rvalue. This is what std::forward does. std::move always casts as an rvalue; std::forward conditionally casts as an rvalue. But how to distinguish? Look at T: 1 if param is an lvalue-reference, T = Widget&; 2 if param is an rvalue-reference, T = Widget. T must be given to std::forward so it can decide whether to cast its parameter as an rvalue or not. process(std::forward<T>(param)); 11
  • 56. Usability enhancements Type deduction Move semantics Lambda expressions Subtle forwarding and rvalue references template<typename T> class vector { public: void push_back(T&& x); }; is not a forwarding reference. Writing std::vector<Widget> v; causes the template to be instanciated as class vector<Widget> { public: void push_back(Widget&& x); }; which involves no type deduction. 11 R
  • 57. Usability enhancements Type deduction Move semantics Lambda expressions Subtle forwarding and rvalue references A template forwarding reference must have the form T&&. Hence, the two following references do not qualify for being forwarding references. template<typename T> void f(const T&& param); template<typename T> void f(std::vector<T>&& param); 11 R
  • 58. Usability enhancements Type deduction Move semantics Lambda expressions Subtle forwarding and rvalue references The variadic templates of emplace involve type deduction. template<typename T> class vector { public: template<typename... Args> void emplace(Args&& args); }; 11 R
  • 59. Usability enhancements Type deduction Move semantics Lambda expressions Implementation of std::move in C++11 template<typename T> typename remove_reference<T>::type&& move(T&& param) { using ReturnType = typename remove_reference<T>::type&&; return static_cast<ReturnType>(param); } param is a forwarding reference: if param is an lvalue-reference, T = Widget&; if param is an rvalue-reference, T = Widget. Steps: 1 remove_reference<T>::type returns Widget; 2 remove_reference<T>::type&& returns Widget&&; 3 static_cast<Widget&&> casts param as an rvalue. 11 R
  • 60. Usability enhancements Type deduction Move semantics Lambda expressions Implementation of std::move in C++14 std::remove_reference_t<T> replaces typename remove_reference<T>::type. std::move can elegantly be written as template<typename T> decltype(auto) move(T&& param) { using ReturnType = remove_reference_t<T>&&; return static_cast<ReturnType>(param); } 14 R
  • 61. Usability enhancements Type deduction Move semantics Lambda expressions Lambda expressions auto lambda = [](int x, int y) -> int { return x + y; }; std::cout << lambda(2, 3) << std::endl; Components: (int x, int y) is the parameters list; int after -> is the return type; {...} is the lambda body. A lambda can be executed upon declaration with trailing“()”: std::cout << [](int x, int y) -> int { return x + y; }(2, 3) << std::endl; 11
  • 62. Usability enhancements Type deduction Move semantics Lambda expressions std::for each and std::transform Apply a lambda to each element of an iterator: void f(std::vector<int>& v) { std::for_each(v.begin(), v.end(), [](int p) { std::cout << p << std::endl; }); } Modify each element with a lambda: void f(std::vector<double>& v) { std::transform(v.begin(), v.end(), v.begin(), [](double d) { return d < 0.00001 ? 0 : d; }); } C++03 already had std::for_each and std::transform, but cumbersome functors were necessary since lambdas were not available. 11
  • 63. Usability enhancements Type deduction Move semantics Lambda expressions std::for each and std::transform If the body is not a single return expression, the type has to be explicitely stated: void f(std::vector<double>& v) { std::transform(v.begin(), v.end(), v.begin(), [](double d) -> double { if (d < 0.0001) return 0; else return d; }); } 11
  • 64. Usability enhancements Type deduction Move semantics Lambda expressions Lambda captures [] allows to capture other variables from the scope. void f(std::vector<double>& v, double epsilon) { std::transform(v.begin(), v.end(), v.begin(), [epsilon](double d) -> double { if (d < epsilon) return 0; else return d; }); } We can capture by both reference and value. 11
  • 65. Usability enhancements Type deduction Move semantics Lambda expressions Generalized lambda captures An element of the capture can be initialized with =. This allows renaming of variables and to capture by moving. int x = 4; auto y = [&r = x, x = x+1]() -> int { r += 2; return x+2; }(); // Updates ::x to 6, and initializes y to 7 std::unique_ptr<int> ptr(new int(10)); auto lambda = [value = std::move(ptr)] { return *value; }; std::unique_ptr can be moved but not copied. Capture by move is the only way to capture a std::unique_ptr. 14
  • 66. Usability enhancements Type deduction Move semantics Lambda expressions Generic lambdas Lambda function parameters may be declared auto. auto lambda = [](auto x, auto y) { return x + y; }; 14
  • 67. Usability enhancements Type deduction Move semantics Lambda expressions Improved return type deduction C++14 allows deduced return types for every function, not only those of the form return expression. void f(std::vector<double>& v, double epsilon) { std::transform(v.begin(), v.end(), v.begin(), [epsilon](auto d) { if (d < epsilon) return 0; else return d; }); } 14
  • 68. Usability enhancements Type deduction Move semantics Lambda expressions Remaining modern C++ topics type traits (std::enable if, std::is pointer. . . ); smart pointers; threading facilities; noexcept; std::function; std::bind and std::ref; std::regex; extern template; inline namespace. . .