Kevin Ottens & David Faure
Akademy-fr / Capitole du Libre 2013
C++11 feels like a new language
Bjarne Stroustrup
Sauf pour Visual Studio qui a un peu de retard…
auto
int val = 42;
const int cval = 42;
Contact *c = new Contact;
std::vector<int> values = ...;
for (std::vector<int>::const_iterator it = values.cbegin(), end = values.cend();
it != end; it++) {
int val = *it;
std::cout << val << endl;
}
auto val = 42;
const auto cval = 42;
auto c = new Contact;
std::vector<int> values = ...;
for (auto it = values.cbegin(), end = values.cend();
it != values.cend(); it++) {
auto val = *it;
std::cout << val << endl;
}
std::vector<int> values = ...;
for (std::vector<int>::const_iterator it = values.cbegin(), end = values.cend();
it != end; it++) {
int val = *it;
std::cout << val << endl;
}
auto
std::vector<int> values = ...;
for (auto it = values.cbegin(), end = values.cend();
it != end; it++) {
auto val = *it;
std::cout << val << endl;
}
std::vector<int> values = ...;
for (auto val : values) {
std::cout << val << endl;
}
std::vector<int> values = ...;
for (auto &val : values) {
val = val * val;
}
class Parent
{
public:
Parent(int i) : value(i) { /* do something */ }
protected:
int value;
};
class Child : public Parent
{
public:
Child(int i) : Parent(i), flag(false) {}
protected:
bool flag;
};
class Parent
{
public:
Parent(int i) : value(i) { /* do something */ }
protected:
int value;
};
class Child : public Parent
{
public:
using Parent::Parent;
protected:
bool flag = false;
};
class MyClass
{
public:
MyClass(int i, int j) { init(i, j); }
MyClass(int i, const char *j) { init(i, atoi(j)); }
private:
void init(int i, int j) { /* do something */ }
};
class MyClass
{
public:
MyClass(int i, int j) { /* do something */ }
MyClass(int i, const char *j) : MyClass(i, atoi(j)) {}
};
float array[] = { 0.0f, 1.42f, 42.3f };
int value = 7;
int other(8);
Circle c(Point(0, 0), 12);
std::vector<int> values;
values.push_back(1);
values.push_back(2);
float array[] = { 0.0f, 1.42f, 42.3f };
int value = {7};
int other{8};
Circle c1{ Point{0, 0}, 12 };
Circle c2{ {0, 0}, 12 };
std::vector<int> values{ 1, 2 };
#include <initializer_list>
class SharedMemList
{
public:
SharedMemList(std::initializer_list<int> l)
{
for (int param : l) {
storeInSharedMem(param);
}
}
...
};
nullptr
void f(int value);
void f(void *data);
...
f(0); // int
f(0L); // ambiguous...
f(NULL); // ambiguous...
void f(int value);
void f(void *data);
...
f(0); // int
f(nullptr); // void*
override
class Parent
{
public:
virtual void method();
};
class Child : public Parent
{
public:
void method() override;
};
class Parent
{
public:
virtual void method(int value);
};
class Child : public Parent
{
public:
void method() override; // error!
};
final
class Parent
{
public:
virtual void method() final;
};
class Child : public Parent
{
public:
void method(); // error!
};
class Parent final
{
public:
virtual void method();
};
class Child : public Parent // error!
{
};
std::shared_ptr
using namespace std;
shared_ptr<Contact> c{new Contact(name, address)};
auto c = make_shared<Contact>(name, address);
// We assume `class Employee : public Contact`
// Ouch!
shared_ptr<Employee> e{ dynamic_cast<Employee>(c.get()) };
// Better!
auto e = dynamic_pointer_cast<Employee>(c);
std::weak_ptr
using namespace std;
shared_ptr<Contact> shared_c
= make_shared<Contact>(name, address);
// No refcount
weak_ptr<Contact> weak_c = shared_c;
// Refcount
shared_ptr<Contact> shared_c2 = weak_c.lock();
std::unique_ptr
class Contact
{
...
private:
std::unique_ptr<RecordHandle> m_dbHandle;
};
void writeConfig()
{
std::unique_ptr<FileHandle> file;
...
if (error) return;
...
}
auto surface = [](int w, int h) { return w * h; };
int s = surface(4, 5);
std::vector<int> v{ 1, 2, 3, 4, 5 };
std::transform(v.begin(), v.end(),
v.begin(),
[](int v) { return v * v; });
// For Qt 5 users
connect(lineEdit, &QLineEdit::textChanged,
[](const QString &text) { qDebug() << text; });
std::vector<int> in{ 2, 3, 4, 6, 9 };
std::vector<int> out(3);
int x = 2;
auto multipleOfX = [x](int y) { return y % x == 0; };
x = 3;
std::copy_if(in.begin(), in.end(),
out.begin(), multipleOfX);
// out contains 2, 4 and 6
std::vector<int> in{ 2, 3, 4, 6, 9 };
std::vector<int> out(3);
int x = 2;
auto multipleOfX = [&x](int y) { return y % x == 0; }
x = 3;
std::copy_if(in.begin(), in.end(),
out.begin(), multipleOfX);
// out contains 3, 6 and 9
QList<QAction*> widthActions = ...;
PaintArea *area = ...;
for (QAction *action : widthActions) {
const int width = action->property("width").toInt();
connect(action, &QAction::triggered,
[width, area]() {
area->setPenWidth(width);
}
);
}
std::function
using namespace std;
float binder(float x, function<float(float, float)> f)
{
return f(x, x);
}
void register(const char *type,
function<Widget*(int)> factory);
std::mem_fn
auto widgetIsHidden = std::mem_fn(&Widget::isHidden);
Widget *w = ...;
if (widgetIsHidden(w)) { ... }
std::vector<Widget*> widgets = ...;
std::cout << "Hidden widgets: "
<< std::count_if(widgets.cbegin(),
widgets.cend(),
widgetIsHidden);
std::bind
float square(float a) { return a * a; }
float sum(float a, float b) { return a + b; }
auto square42 = std::bind(square, 42);
std::cout << square42() << std::endl; // 1764
auto sum41 = std::bind(sum, 41, std::placeholders::_1);
std::cout << sum41(1) << std::endl; // 42
bool less_than(int a, int b)
{
return x < y;
}
std::vector<int> in{ 1, 2, 4, 8, 16 };
std::vector<int> out(3);
using namespace std::placeholders;
std::copy_if(in.begin(), in.end(),
out.begin(), std::bind(less_than, _1, 8));
// out contains 1, 2 and 4
struct Weight {
explicit Weight(double kg) : kilograms(kg) {}
double kilograms;
};
constexpr Weight operator "" _kg(double kg) {
return Weight{kg};
}
constexpr Weight operator "" _lb(double lb) {
return Weight{lb * 0.45359237};
}
// Assume operator + exists for Weight
auto weight = 2.0_kg + 3.0_lb;
// Assuming types Length and Area
constexpr Length operator "" _m(double m) {
return Length{m};
}
constexpr Length operator "" _cm(double cm) {
return Length{cm/100.0};
}
constexpr Area operator "" _sqm(double sqm) {
return Area{sqm};
}
...
// Assuming proper operators *, + and ==
// for Length and Area
auto area = 10.0_sqm + (2.0_m * 120.0_cm);
if (area == 12.5_sqm) {
...
}
int maximum(int n)
{
return n;
}
template<typename... Args>
int maximum(int n, Args... args)
{
return std::max(n, maximum(args...));
}
auto m = maximum(25, 42, 10, 30);
// m == 42
template<typename ... Types> class Tuple;
template<> class Tuple<> {};
template<typename Head, typename ... Tail>
class Tuple<Head, Tail...> {
Head m_head;
Tuple<Tail...> m_tail;
public:
Tuple(const Head &head, const Tail & ... tail)
: m_head(head), m_tail(tail...) {}
Head head() const { return m_head; }
Tuple<Tail...> tail() const { return m_tail; }
};
std::thread
// Puts the result in some shared state
void computeFibonacci(int n);
std::thread t1{computeFibonacci, 42};
std::thread t2{
[]() { std::cout << 42 << endl; }
};
t1.join();
t2.join();
std::mutex
std::future
std::async
unsigned long long fibonacci(unsigned n);
...
std::vector<std::future<unsigned long long>> results;
for (int n = 0; n < 45; n++) {
results.push_back(
std::async(launch::async, fibonacci, n)
);
}
for (auto &result : results) {
std::cout << result.get() << std::endl;
}