SlideShare a Scribd company logo
1 of 67
Download to read offline
Antony Polukhin
Полухин Антон
Полезный constexpr
Содержание
●
Старое и известное
●
Старое и незнакомое
●
Ближайшее будущее
●
Очень далёкое будущее
Полезный constexpr
C++14
C++26
Старое и известное
Полезный constexpr
Старое и известное
#include <boost/array.hpp>
inline unsigned factorial(unsigned n) {
return n ? n * factorial(n - 1) : 1;
}
Полезный constexpr 5 / 67
Старое и известное
#include <boost/array.hpp>
inline unsigned factorial(unsigned n) {
return n ? n * factorial(n - 1) : 1;
}
boost::array<int, factorial(3)> a;
Полезный constexpr 6 / 67
Старое и известное
error: call to non-constexpr function ‘unsigned int factorial(unsigned int)’
boost::array<int, factorial(3)> a;
~~~~~~~~~^~~
error: call to non-constexpr function ‘unsigned int factorial(unsigned int)’
note: in template argument for type ‘long unsigned int’
boost::array<int, factorial(3)> a;
Полезный constexpr 7 / 67
Старое и известное
#include <array>
constexpr unsigned factorial(unsigned n) {
return n ? n * factorial(n - 1) : 1;
}
std::array<int, factorial(3)> a;
Полезный constexpr 8 / 67
Старое и известное (2)
#include <stdexcept>
int do_something(unsigned n) {
constexpr auto i = 7 + 20;
// ...
return i;
}
Полезный constexpr 9 / 67
Старое и известное (2)
#include <stdexcept>
int do_something(unsigned n) {
constexpr auto i = 7 + 20;
// ...
return i;
}
Полезный constexpr 10 / 67
Старое и известное (2)
#include <stdexcept>
constexpr unsigned factorial(unsigned n) {
if (n > 10)
throw std::out_of_range("n is greater than 10");
return n ? n * factorial(n - 1) : 1;
}
int do_something(unsigned n) {
auto i = factorial(17);
// ...
return i;
}
Полезный constexpr 11 / 67
Старое и известное (2)
#include <stdexcept>
constexpr unsigned factorial(unsigned n) {
if (n > 10)
throw std::out_of_range("n is greater than 10");
return n ? n * factorial(n - 1) : 1;
}
int do_something(unsigned n) {
throw std::out_of_range("n is greater than 10");
}
Полезный constexpr 12 / 67
Старое и известное (2)
#include <stdexcept>
constexpr unsigned factorial(unsigned n) {
if (n > 10)
throw std::out_of_range("n is greater than 10");
return n ? n * factorial(n - 1) : 1;
}
int do_something(unsigned n) {
constexpr auto i = factorial(17);
// ...
return i;
}
Полезный constexpr 13 / 67
Старое и известное (2)
In function ‘int do_something(unsigned int)’:
in constexpr expansion of ‘factorial(17)’
error: expression ‘<throw-expression>’ is not a constant expression
throw std::out_of_range("n is greater than 10");
Полезный constexpr 14 / 67
Старое и незнакомое
Полезный constexpr
Статическая
инициализация
All static initialization strongly happens before any
dynamic initialization.
int do_something(unsigned n) {
static const int i = 17;
Полезный constexpr 16 / 67
Статическая
инициализация
All static initialization strongly happens before any
dynamic initialization.
int do_something(unsigned n) {
static const int i = n;
Полезный constexpr 17 / 67
Статическая
инициализация
All static initialization strongly happens before any
dynamic initialization.
int do_something(unsigned n) {
static const int i = factorial(7);
Полезный constexpr 18 / 67
Старое и незнакомое
namespace std {
class mutex {
public:
constexpr mutex() noexcept;
~mutex();
mutex(const mutex&) = delete;
mutex& operator=(const mutex&) = delete;
/*...*/
};
}
Полезный constexpr 19 / 67
Старое и незнакомое
namespace std {
class mutex {
public:
constexpr mutex() noexcept;
~mutex();
mutex(const mutex&) = delete;
mutex& operator=(const mutex&) = delete;
/*...*/
};
}
Полезный constexpr 20 / 67
Статическая
инициализация
A constant initializer for a variable or temporary object o is an
initializer whose full-expression is a constant expression, except
that if o is an object, such an initializer may also invoke
constexpr constructors for o and its subobjects even if those
objects are of non-literal class types.
[ Note: Such a class may have a non-trivial destructor. — end
note ]
All static initialization strongly happens before any dynamic
initialization.
Полезный constexpr 21 / 67
Старое и незнакомое
// 1.cpp
namespace {
std::mutex m;
}
std::mutex& global_mutex() { return m; }
// 2.cpp
std::vector<int> data = []() {
std::lock_guard<std::mutex> l(global_mutex()); // Oops?
return some_creepy_api();
}();
Полезный constexpr 22 / 67
Старое и незнакомое (2)
Полезный constexpr
Старое и незнакомое (2)
// Bubble-like sort. Anything complex enough will work
template <class It>
void sort(It first, It last) { /*...*/ }
inline int generate(int i) {
int a[7] = {3, 7, 4, i, 8, 0, 1};
sort(a + 0, a + 7);
return a[0] + a[6];
}
int no_constexpr() { return generate(1); }
Полезный constexpr 24 / 67
Старое и незнакомое (2)
no_constexpr():
movabs rax, 30064771075
mov DWORD PTR [rsp-20], 0
lea rdx, [rsp-40]
mov QWORD PTR [rsp-40], rax
lea rsi, [rdx+28]
movabs rax, 4294967300
mov QWORD PTR [rsp-32], rax
lea rax, [rsp-40]
mov DWORD PTR [rsp-16], 1
add rax, 4
mov DWORD PTR [rsp-24], 8
Полезный constexpr
mov rcx, rax
.L2:
add rax, 4
cmp rax, rsi
je .L8
.L6:
mov edi, DWORD PTR [rax]
mov r8d, DWORD PTR [rdx]
cmp edi, r8d
jge .L2
mov DWORD PTR [rax], r8d
add rax, 4
mov DWORD PTR [rdx], edi
cmp rax, rsi
jne .L6
.L8:
lea rax, [rcx+4]
cmp rax, rsi
je .L3
mov rdx, rcx
mov rcx, rax
jmp .L6
.L3:
mov eax,DWORD PTR[rsp-16]
add eax,DWORD PTR[rsp-40]
ret 25 / 67
Старое и незнакомое (2)
// Bubble-like sort. Anything complex enough will work
template <class It>
constexpr void sort(It first, It last) { /*...*/ }
constexpr int generate(int i) {
int a[7] = {3, 7, 4, i, 8, 0, 1};
sort(a + 0, a + 7);
return a[0] + a[6];
}
int no_constexpr() { return generate(1); }
Полезный constexpr 26 / 67
Старое и незнакомое (2)
no_constexpr():
mov eax, 8
ret
Полезный constexpr 27 / 67
А почему так?
Полезный constexpr 28 / 67
Анатомия компилятора (упрощённо)
Полезный constexpr
С++С Fortran ...
Middle end
Ada Go
IR
IR
Power PCx86 Alpha ...Arm x86_64
29 / 67
Анатомия компилятора (без constexpr)
Полезный constexpr
С++С Fortran ...
Middle end
Ada Go
IR
IR
:(
Power PCx86 Alpha ...Arm x86_64
30 / 67
Старое и незнакомое (2)
no_constexpr():
movabs rax, 30064771075
mov DWORD PTR [rsp-20], 0
lea rdx, [rsp-40]
mov QWORD PTR [rsp-40], rax
lea rsi, [rdx+28]
movabs rax, 4294967300
mov QWORD PTR [rsp-32], rax
lea rax, [rsp-40]
mov DWORD PTR [rsp-16], 1
add rax, 4
mov DWORD PTR [rsp-24], 8
Полезный constexpr
mov rcx, rax
.L2:
add rax, 4
cmp rax, rsi
je .L8
.L6:
mov edi, DWORD PTR [rax]
mov r8d, DWORD PTR [rdx]
cmp edi, r8d
jge .L2
mov DWORD PTR [rax], r8d
add rax, 4
mov DWORD PTR [rdx], edi
cmp rax, rsi
jne .L6
.L8:
lea rax, [rcx+4]
cmp rax, rsi
je .L3
mov rdx, rcx
mov rcx, rax
jmp .L6
.L3:
mov eax,DWORD PTR[rsp-16]
add eax,DWORD PTR[rsp-40]
ret 31 / 67
Анатомия компилятора (constexpr)
Полезный constexpr
С++С Fortran ...
Middle end
Ada Go
IR
IR
:)
Power PCx86 Alpha ...Arm x86_64
32 / 67
Старое и незнакомое (2)
no_constexpr():
mov eax, 8
ret
Полезный constexpr 33 / 67
Старое и незнакомое (3)
Полезный constexpr
Старое и незнакомое (3)
#include <stdexcept>
constexpr int factorial(int n) {
return n ? n * factorial(n - 1) : 1;
}
int do_something(unsigned n) {
constexpr auto i = factorial(27);
// ...
return i;
}
Полезный constexpr 35 / 67
Старое и незнакомое (3)
main.cpp: In function ‘int do_something(unsigned int)’:
main.cpp:200:33: in constexpr expansion of ‘factorial(27)’
main.cpp:197:29: in constexpr expansion of ‘factorial((n + -1))’
main.cpp:197:29: in constexpr expansion of ‘factorial((n + -1))’
<...>
main.cpp:197:29: in constexpr expansion of ‘factorial((n + -1))’
main.cpp:197:29: in constexpr expansion of ‘factorial((n + -1))’
main.cpp:197:29: in constexpr expansion of ‘factorial((n + -1))’
main.cpp:200:36: error: overflow in constant expression [-fpermissive]
constexpr auto i = factorial(27);
^
Полезный constexpr 36 / 67
Итого:
Полезный constexpr
Constexpr: * Позволяет использовать функции для вычисления констант
* «Заставляет» вычислять константы
* Позволяет статически инициализировать объекты
* Оптимизирует код
* Позволяет проверять на UB
Полезный constexpr 38 / 67
Ближайшее будущее
Полезный constexpr
Constexpr new А давайте разрешим вызывать new в constexpr функциях,
если в этой же constexpr функции память освобождается. Ну
и деструкторы разрешим делать constexpr:
constexpr auto precompute_series(int n, int i) {
std::vector<int> v(n);
/*...*/
return v[i];
}
Полезный constexpr 40 / 67
Constexpr new А давайте будем память выделенную через new в constexpr
функциях записывать прям в бинарник и не вызывать
деструктор для объекта [*] (прям как при константной
инициализации):
constexpr auto precompute_whole_series(int n) {
std::vector<int> v(n);
/*...*/
return v;
}
[*] - есть тонкости
Полезный constexpr 41 / 67
Constexpr new А давайте будем память выделенную через new в constexpr
функциях записывать прям в бинарник и не вызывать
деструктор для объекта [*] (прям как при константной
инициализации):
const std::string we_need_this = "Something usefull";
const std::string time_format = "YYYY-MM-DDTHH:MM:SS";
Полезный constexpr 42 / 67
Ближайшее будущее (2)
Полезный constexpr
Регулярки Регулярки медленно инициализаируются:
bool is_valid_mail(std::string_view mail) {
// ~260 sµ
static const std::regex mail_regex(R"((?:(?:[^<>()[].,;:s@"]+
(?:.[^<>()[].,;:s@"]+)*)|".+")@(?:(?:[^<>()[].,;:s@"]+.)+
[^<>()[].,;:s@"]{2,}))");
return std::regex_match(
std::cbegin(mail),
std::cend(mail),
mail_regex
);
}Полезный constexpr 44 / 67
Constexpr regex Ой, смотрите, мы же теперь можем сделать constexpr
std::regex:
bool is_valid_mail(std::string_view mail) {
// Проинициализируется на этапе компиляции
static const std::regex mail_regex(/*...*/);
return std::regex_match(
std::cbegin(mail),
std::cend(mail),
mail_regex
);
}
Полезный constexpr 45 / 67
Constexpr
boyer_moore_ho
rspool_searcher
std::boyer_moore_horspool_searcher — иногда ищет быстро, а
вот конструируется медленно.
---------------------------------------------------
Benchmark Time CPU Iterations
---------------------------------------------------
BM_bmh_construction 118 ns 118 ns 4644219
BM_bmh_construction_huge 184 ns 184 ns 3779484
BM_bmh_apply 34 ns 34 ns 20578297
BM_bmh_apply_huge 73 ns 73 ns 9311461
Можно будет сделать constexpr конструктор, и наслаждаться
конструированием на этапе компиляции, а не на рантайме.
Полезный constexpr 46 / 67
Очень далёкое будущее
Полезный constexpr
Рефлексия
struct User {
std::string name;
unsigned age;
[[orm "id"]]
unsigned uuid;
};
Полезный constexpr 48 / 67
Рефлексия
// Синтаксис изменится!
template <class Db, class Data>
void fill_from_db(Db& db, Data& d) {
auto it = $d.fields.name("id") || $d.fields.attributes("orm "id"").fields()[0];
db.start(*it);
for (auto field: $d.fields()) {
constexpr std::string name {
field.attribute("orm") ? field.attribute("orm") : field.name()
};
db[name] >> field;
}
}
Полезный constexpr 49 / 67
Рефлексия
// Синтаксис изменится!
template <class Db, class Data>
void fill_from_db(Db& db, Data& d) { // User
auto it = $d.fields.name("id") || $d.fields.attributes("orm "id"").fields()[0];
db.start(*it);
for (auto field: $d.fields()) {
constexpr std::string name {
field.attribute("orm") ? field.attribute("orm") : field.name()
};
db[name] >> field;
}
}
Полезный constexpr 50 / 67
Рефлексия
// Синтаксис изменится!
template <class Db, class Data>
void fill_from_db(Db& db, Data& d) { // User
auto it = $d.fields.name("id") || $d.fields.attributes("orm "id"").fields()[0];
db.start(*it); // d.uuid
for (auto field: $d.fields()) {
constexpr std::string name {
field.attribute("orm") ? field.attribute("orm") : field.name()
};
db[name] >> field;
}
}
Полезный constexpr 51 / 67
Рефлексия
// Синтаксис изменится!
template <class Db, class Data>
void fill_from_db(Db& db, Data& d) { // User
auto it = $d.fields.name("id") || $d.fields.attributes("orm "id"").fields()[0];
db.start(*it); // d.uuid
for (auto field: $d.fields()) {
constexpr std::string name {
field.attribute("orm") ? field.attribute("orm") : field.name()
};
db[name] >> field; // «age», «name» => d.age, d.name
}
}
Полезный constexpr 52 / 67
Рефлексия
// Синтаксис изменится!
template <class Db, class Data>
void fill_from_db(Db& db, Data& d) {
auto it = $d.fields.name("id") || $d.fields.attributes("orm "id"").fields()[0];
db.start(*it);
for (auto field: $d.fields()) { // constexpr std::vector<field>
constexpr std::string name {
field.attribute("orm") ? field.attribute("orm") : field.name()
};
db[name] >> field;
}
}
Полезный constexpr 53 / 67
Рефлексия
template <class Db>
void fill_from_db(Db& db, User& d) {
db.start(d.uuid);
db["age"] >> d.age;
db["name"] >> d.name;
}
Полезный constexpr 54 / 67
Рефлексия
int main() {
Mongo m;
User u{.uuid=42};
fill_from_db(m, u)
std::cout << "User with id = 42 is " << u.name;
}
Полезный constexpr 55 / 67
Плюшки для рефлексии
Полезный constexpr
Рефлексия и проблемы
// Синтаксис изменится!
template <class Db, class Data>
void fill_from_db(Db& db, class Data& d) {
auto it = $d.fields.name("id") || $d.fields.attributes("orm "id"").fields()[0];
db.start(*it);
for (auto field: $d.fields()) { // constexpr std::vector<field>
constexpr std::string name {
field.attribute("orm") ? field.attribute("orm") : field.name()
};
db[name] >> field;
}
}
Полезный constexpr 57 / 67
constexpr функции
Полезный constexpr
С++С Fortran ...
Middle end
Ada Go
IR
IR
Power PCx86 Alpha ...Arm x86_64
Smth.cpp
58 / 67
constexpr! функции
Полезный constexpr
С++С Fortran ...
Middle end
Ada Go
IR
IR
Power PCx86 Alpha ...Arm x86_64
Smth.cpp
59 / 67
Рефлексирующие классы
Полезный constexpr
Метаклассы
$orm User {
std::string name;
unsigned age;
[[orm "id"]]
unsigned uuid;
};
Полезный constexpr 61 / 67
Метаклассы
$orm User {
std::string name;
unsigned age;
[[orm "id"]]
unsigned uuid;
};
Полезный constexpr 62 / 67
Метаклассы
int main() {
Mongo m;
User u(42, m);
std::cout << "User with id = 42 is " << u.name();
}
Полезный constexpr 63 / 67
Метаклассы
$class orm {
for (auto field: $this->fields()) {
$"auto " + field.name() + "() const { return m_" + field.name() + "; }";
$"void set_" + field.name() + "(auto v) { m_" + field.name() + "=std::move(v); }";
field.make_private().set_name("m_" + field.name());
}
$"template <class Db>" +
$this->name() + $"(unsigned id, Db& db) : m_uuid(id) { " +
"fill_from_db(db, *this);" +
"}";
};
Полезный constexpr 64 / 67
Метаклассы
class User {
std::string m_name;
unsigned m_age;
unsigned m_uuid;
public:
auto name() const { return m_name; }
auto age() const { return m_age; }
auto uuid() const { return m_uuid; }
// ...
template <class Db>
User(unsigned id, Db& db) : m_uuid(id) { fill_from_db(db, *this); }
};
Полезный constexpr 65 / 67
Спасибо
Полухин Антон
Старший разработчик Yandex.Taxi
antoshkka@yandex-team.ru
antoshkka@gmail.com
https://github.com/apolukhin
https://stdcpp.ru/

More Related Content

What's hot

Лекция 8. Intel Threading Building Blocks
Лекция 8. Intel Threading Building BlocksЛекция 8. Intel Threading Building Blocks
Лекция 8. Intel Threading Building BlocksMikhail Kurnosov
 
Никита Глушков, К вопросу о реализации кроссплатформенных фреймворков
Никита Глушков, К вопросу о реализации кроссплатформенных фреймворковНикита Глушков, К вопросу о реализации кроссплатформенных фреймворков
Никита Глушков, К вопросу о реализации кроссплатформенных фреймворковSergey Platonov
 
ПВТ - осень 2014 - Лекция 4 - Стандарт POSIX Threads. Реентерабельность. Сигн...
ПВТ - осень 2014 - Лекция 4 - Стандарт POSIX Threads. Реентерабельность. Сигн...ПВТ - осень 2014 - Лекция 4 - Стандарт POSIX Threads. Реентерабельность. Сигн...
ПВТ - осень 2014 - Лекция 4 - Стандарт POSIX Threads. Реентерабельность. Сигн...Alexey Paznikov
 
ПВТ - весна 2015 - Лекция 3. Реентерабельность. Сигналы. Локальные данные пот...
ПВТ - весна 2015 - Лекция 3. Реентерабельность. Сигналы. Локальные данные пот...ПВТ - весна 2015 - Лекция 3. Реентерабельность. Сигналы. Локальные данные пот...
ПВТ - весна 2015 - Лекция 3. Реентерабельность. Сигналы. Локальные данные пот...Alexey Paznikov
 
ПВТ - весна 2015 - Лекция 8. Многопоточное программирование без использования...
ПВТ - весна 2015 - Лекция 8. Многопоточное программирование без использования...ПВТ - весна 2015 - Лекция 8. Многопоточное программирование без использования...
ПВТ - весна 2015 - Лекция 8. Многопоточное программирование без использования...Alexey Paznikov
 
ПВТ - осень 2014 - Лекция 5 - Многопоточное программирование в языке С++. Р...
ПВТ - осень 2014 - Лекция 5 - Многопоточное программирование в языке С++.   Р...ПВТ - осень 2014 - Лекция 5 - Многопоточное программирование в языке С++.   Р...
ПВТ - осень 2014 - Лекция 5 - Многопоточное программирование в языке С++. Р...Alexey Paznikov
 
ПВТ - осень 2014 - Лекция 6 - Атомарные операции. Внеочередное выполнение инс...
ПВТ - осень 2014 - Лекция 6 - Атомарные операции. Внеочередное выполнение инс...ПВТ - осень 2014 - Лекция 6 - Атомарные операции. Внеочередное выполнение инс...
ПВТ - осень 2014 - Лекция 6 - Атомарные операции. Внеочередное выполнение инс...Alexey Paznikov
 
ПВТ - весна 2015 - Лекция 5. Многопоточное программирование в С++. Синхрониза...
ПВТ - весна 2015 - Лекция 5. Многопоточное программирование в С++. Синхрониза...ПВТ - весна 2015 - Лекция 5. Многопоточное программирование в С++. Синхрониза...
ПВТ - весна 2015 - Лекция 5. Многопоточное программирование в С++. Синхрониза...Alexey Paznikov
 
Некоторые паттерны реализации полиморфного поведения в C++ – Дмитрий Леванов,...
Некоторые паттерны реализации полиморфного поведения в C++ – Дмитрий Леванов,...Некоторые паттерны реализации полиморфного поведения в C++ – Дмитрий Леванов,...
Некоторые паттерны реализации полиморфного поведения в C++ – Дмитрий Леванов,...Yandex
 
Использование шаблонов и RTTI для конфигурации симулятора флеш-накопителя - Г...
Использование шаблонов и RTTI для конфигурации симулятора флеш-накопителя - Г...Использование шаблонов и RTTI для конфигурации симулятора флеш-накопителя - Г...
Использование шаблонов и RTTI для конфигурации симулятора флеш-накопителя - Г...Yandex
 
Быстрые конструкции в Python - Олег Шидловский, Python Meetup 26.09.2014
Быстрые конструкции в Python - Олег Шидловский, Python Meetup 26.09.2014Быстрые конструкции в Python - Олег Шидловский, Python Meetup 26.09.2014
Быстрые конструкции в Python - Олег Шидловский, Python Meetup 26.09.2014Python Meetup
 
Павел Сушин «Асинхронное программирование на С++: callbacks, futures, fibers»
Павел Сушин «Асинхронное программирование на С++: callbacks, futures, fibers»Павел Сушин «Асинхронное программирование на С++: callbacks, futures, fibers»
Павел Сушин «Асинхронное программирование на С++: callbacks, futures, fibers»Platonov Sergey
 
Python&Printer / Андрей Пучко / penta.by
Python&Printer / Андрей Пучко / penta.byPython&Printer / Андрей Пучко / penta.by
Python&Printer / Андрей Пучко / penta.byPython Meetup
 
Модель памяти C++ - Андрей Янковский, Яндекс
Модель памяти C++ - Андрей Янковский, ЯндексМодель памяти C++ - Андрей Янковский, Яндекс
Модель памяти C++ - Андрей Янковский, ЯндексYandex
 
ПВТ - осень 2014 - Лекция 7. Многопоточное программирование без блокировок. М...
ПВТ - осень 2014 - Лекция 7. Многопоточное программирование без блокировок. М...ПВТ - осень 2014 - Лекция 7. Многопоточное программирование без блокировок. М...
ПВТ - осень 2014 - Лекция 7. Многопоточное программирование без блокировок. М...Alexey Paznikov
 
Поговорим о микрооптимизациях .NET-приложений
Поговорим о микрооптимизациях .NET-приложенийПоговорим о микрооптимизациях .NET-приложений
Поговорим о микрооптимизациях .NET-приложенийAndrey Akinshin
 
Лекция 6. Стандарт OpenMP
Лекция 6. Стандарт OpenMPЛекция 6. Стандарт OpenMP
Лекция 6. Стандарт OpenMPMikhail Kurnosov
 

What's hot (20)

Лекция 8. Intel Threading Building Blocks
Лекция 8. Intel Threading Building BlocksЛекция 8. Intel Threading Building Blocks
Лекция 8. Intel Threading Building Blocks
 
Никита Глушков, К вопросу о реализации кроссплатформенных фреймворков
Никита Глушков, К вопросу о реализации кроссплатформенных фреймворковНикита Глушков, К вопросу о реализации кроссплатформенных фреймворков
Никита Глушков, К вопросу о реализации кроссплатформенных фреймворков
 
ПВТ - осень 2014 - Лекция 4 - Стандарт POSIX Threads. Реентерабельность. Сигн...
ПВТ - осень 2014 - Лекция 4 - Стандарт POSIX Threads. Реентерабельность. Сигн...ПВТ - осень 2014 - Лекция 4 - Стандарт POSIX Threads. Реентерабельность. Сигн...
ПВТ - осень 2014 - Лекция 4 - Стандарт POSIX Threads. Реентерабельность. Сигн...
 
Clojure #1
Clojure #1Clojure #1
Clojure #1
 
ПВТ - весна 2015 - Лекция 3. Реентерабельность. Сигналы. Локальные данные пот...
ПВТ - весна 2015 - Лекция 3. Реентерабельность. Сигналы. Локальные данные пот...ПВТ - весна 2015 - Лекция 3. Реентерабельность. Сигналы. Локальные данные пот...
ПВТ - весна 2015 - Лекция 3. Реентерабельность. Сигналы. Локальные данные пот...
 
ПВТ - весна 2015 - Лекция 8. Многопоточное программирование без использования...
ПВТ - весна 2015 - Лекция 8. Многопоточное программирование без использования...ПВТ - весна 2015 - Лекция 8. Многопоточное программирование без использования...
ПВТ - весна 2015 - Лекция 8. Многопоточное программирование без использования...
 
ПВТ - осень 2014 - Лекция 5 - Многопоточное программирование в языке С++. Р...
ПВТ - осень 2014 - Лекция 5 - Многопоточное программирование в языке С++.   Р...ПВТ - осень 2014 - Лекция 5 - Многопоточное программирование в языке С++.   Р...
ПВТ - осень 2014 - Лекция 5 - Многопоточное программирование в языке С++. Р...
 
ПВТ - осень 2014 - Лекция 6 - Атомарные операции. Внеочередное выполнение инс...
ПВТ - осень 2014 - Лекция 6 - Атомарные операции. Внеочередное выполнение инс...ПВТ - осень 2014 - Лекция 6 - Атомарные операции. Внеочередное выполнение инс...
ПВТ - осень 2014 - Лекция 6 - Атомарные операции. Внеочередное выполнение инс...
 
Clojure #2 (2014)
Clojure #2 (2014)Clojure #2 (2014)
Clojure #2 (2014)
 
ПВТ - весна 2015 - Лекция 5. Многопоточное программирование в С++. Синхрониза...
ПВТ - весна 2015 - Лекция 5. Многопоточное программирование в С++. Синхрониза...ПВТ - весна 2015 - Лекция 5. Многопоточное программирование в С++. Синхрониза...
ПВТ - весна 2015 - Лекция 5. Многопоточное программирование в С++. Синхрониза...
 
Некоторые паттерны реализации полиморфного поведения в C++ – Дмитрий Леванов,...
Некоторые паттерны реализации полиморфного поведения в C++ – Дмитрий Леванов,...Некоторые паттерны реализации полиморфного поведения в C++ – Дмитрий Леванов,...
Некоторые паттерны реализации полиморфного поведения в C++ – Дмитрий Леванов,...
 
Использование шаблонов и RTTI для конфигурации симулятора флеш-накопителя - Г...
Использование шаблонов и RTTI для конфигурации симулятора флеш-накопителя - Г...Использование шаблонов и RTTI для конфигурации симулятора флеш-накопителя - Г...
Использование шаблонов и RTTI для конфигурации симулятора флеш-накопителя - Г...
 
Быстрые конструкции в Python - Олег Шидловский, Python Meetup 26.09.2014
Быстрые конструкции в Python - Олег Шидловский, Python Meetup 26.09.2014Быстрые конструкции в Python - Олег Шидловский, Python Meetup 26.09.2014
Быстрые конструкции в Python - Олег Шидловский, Python Meetup 26.09.2014
 
Parallel STL
Parallel STLParallel STL
Parallel STL
 
Павел Сушин «Асинхронное программирование на С++: callbacks, futures, fibers»
Павел Сушин «Асинхронное программирование на С++: callbacks, futures, fibers»Павел Сушин «Асинхронное программирование на С++: callbacks, futures, fibers»
Павел Сушин «Асинхронное программирование на С++: callbacks, futures, fibers»
 
Python&Printer / Андрей Пучко / penta.by
Python&Printer / Андрей Пучко / penta.byPython&Printer / Андрей Пучко / penta.by
Python&Printer / Андрей Пучко / penta.by
 
Модель памяти C++ - Андрей Янковский, Яндекс
Модель памяти C++ - Андрей Янковский, ЯндексМодель памяти C++ - Андрей Янковский, Яндекс
Модель памяти C++ - Андрей Янковский, Яндекс
 
ПВТ - осень 2014 - Лекция 7. Многопоточное программирование без блокировок. М...
ПВТ - осень 2014 - Лекция 7. Многопоточное программирование без блокировок. М...ПВТ - осень 2014 - Лекция 7. Многопоточное программирование без блокировок. М...
ПВТ - осень 2014 - Лекция 7. Многопоточное программирование без блокировок. М...
 
Поговорим о микрооптимизациях .NET-приложений
Поговорим о микрооптимизациях .NET-приложенийПоговорим о микрооптимизациях .NET-приложений
Поговорим о микрооптимизациях .NET-приложений
 
Лекция 6. Стандарт OpenMP
Лекция 6. Стандарт OpenMPЛекция 6. Стандарт OpenMP
Лекция 6. Стандарт OpenMP
 

Similar to C++ CoreHard Autumn 2018. Полезный constexpr - Антон Полухин

Tech Talks @NSU: Как приручить дракона: введение в LLVM
Tech Talks @NSU: Как приручить дракона: введение в LLVMTech Talks @NSU: Как приручить дракона: введение в LLVM
Tech Talks @NSU: Как приручить дракона: введение в LLVMTech Talks @NSU
 
Как приручить дракона: введение в LLVM
Как приручить дракона: введение в LLVMКак приручить дракона: введение в LLVM
Как приручить дракона: введение в LLVMTech Talks @NSU
 
Продолжаем говорить о микрооптимизациях .NET-приложений
Продолжаем говорить о микрооптимизациях .NET-приложенийПродолжаем говорить о микрооптимизациях .NET-приложений
Продолжаем говорить о микрооптимизациях .NET-приложенийAndrey Akinshin
 
Статический анализ кода
Статический анализ кода Статический анализ кода
Статический анализ кода Pavel Tsukanov
 
статический анализ кода
статический анализ кодастатический анализ кода
статический анализ кодаAndrey Karpov
 
Deep Dive C# by Sergey Teplyakov
Deep Dive  C# by Sergey TeplyakovDeep Dive  C# by Sergey Teplyakov
Deep Dive C# by Sergey TeplyakovAlex Tumanoff
 
Дмитрий Прокопцев — R-ссылки в С++11
Дмитрий Прокопцев — R-ссылки в С++11Дмитрий Прокопцев — R-ссылки в С++11
Дмитрий Прокопцев — R-ссылки в С++11Yandex
 
Распространённые ошибки оценки производительности .NET-приложений
Распространённые ошибки оценки производительности .NET-приложенийРаспространённые ошибки оценки производительности .NET-приложений
Распространённые ошибки оценки производительности .NET-приложенийAndrey Akinshin
 
Распространённые ошибки оценки производительности .NET-приложений
Распространённые ошибки оценки производительности .NET-приложенийРаспространённые ошибки оценки производительности .NET-приложений
Распространённые ошибки оценки производительности .NET-приложенийMikhail Shcherbakov
 
Сложности микробенчмаркинга
Сложности микробенчмаркингаСложности микробенчмаркинга
Сложности микробенчмаркингаAndrey Akinshin
 
разработка серверов и серверных приложений лекция №3
разработка серверов и серверных приложений лекция №3разработка серверов и серверных приложений лекция №3
разработка серверов и серверных приложений лекция №3etyumentcev
 
Евгений Крутько — Опыт внедрения технологий параллельных вычислений для повыш...
Евгений Крутько — Опыт внедрения технологий параллельных вычислений для повыш...Евгений Крутько — Опыт внедрения технологий параллельных вычислений для повыш...
Евгений Крутько — Опыт внедрения технологий параллельных вычислений для повыш...Yandex
 
20130429 dynamic c_c++_program_analysis-alexey_samsonov
20130429 dynamic c_c++_program_analysis-alexey_samsonov20130429 dynamic c_c++_program_analysis-alexey_samsonov
20130429 dynamic c_c++_program_analysis-alexey_samsonovComputer Science Club
 
C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...
C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...
C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...corehard_by
 
Сверхоптимизация кода на Python
Сверхоптимизация кода на PythonСверхоптимизация кода на Python
Сверхоптимизация кода на Pythonru_Parallels
 
Сверхоптимизация кода на Python
Сверхоптимизация кода на PythonСверхоптимизация кода на Python
Сверхоптимизация кода на PythonCodeFest
 
Статический и динамический полиморфизм в C++, Дмитрий Леванов
Статический и динамический полиморфизм в C++, Дмитрий ЛевановСтатический и динамический полиморфизм в C++, Дмитрий Леванов
Статический и динамический полиморфизм в C++, Дмитрий ЛевановYandex
 
Опыт разработки статического анализатора кода
Опыт разработки статического анализатора кодаОпыт разработки статического анализатора кода
Опыт разработки статического анализатора кодаAndrey Karpov
 
Intel IPP Samples for Windows - работа над ошибками
Intel IPP Samples for Windows - работа над ошибкамиIntel IPP Samples for Windows - работа над ошибками
Intel IPP Samples for Windows - работа над ошибкамиTatyanazaxarova
 

Similar to C++ CoreHard Autumn 2018. Полезный constexpr - Антон Полухин (20)

Tech Talks @NSU: Как приручить дракона: введение в LLVM
Tech Talks @NSU: Как приручить дракона: введение в LLVMTech Talks @NSU: Как приручить дракона: введение в LLVM
Tech Talks @NSU: Как приручить дракона: введение в LLVM
 
Как приручить дракона: введение в LLVM
Как приручить дракона: введение в LLVMКак приручить дракона: введение в LLVM
Как приручить дракона: введение в LLVM
 
Продолжаем говорить о микрооптимизациях .NET-приложений
Продолжаем говорить о микрооптимизациях .NET-приложенийПродолжаем говорить о микрооптимизациях .NET-приложений
Продолжаем говорить о микрооптимизациях .NET-приложений
 
Статический анализ кода
Статический анализ кода Статический анализ кода
Статический анализ кода
 
статический анализ кода
статический анализ кодастатический анализ кода
статический анализ кода
 
Deep Dive C# by Sergey Teplyakov
Deep Dive  C# by Sergey TeplyakovDeep Dive  C# by Sergey Teplyakov
Deep Dive C# by Sergey Teplyakov
 
Дмитрий Прокопцев — R-ссылки в С++11
Дмитрий Прокопцев — R-ссылки в С++11Дмитрий Прокопцев — R-ссылки в С++11
Дмитрий Прокопцев — R-ссылки в С++11
 
Распространённые ошибки оценки производительности .NET-приложений
Распространённые ошибки оценки производительности .NET-приложенийРаспространённые ошибки оценки производительности .NET-приложений
Распространённые ошибки оценки производительности .NET-приложений
 
Распространённые ошибки оценки производительности .NET-приложений
Распространённые ошибки оценки производительности .NET-приложенийРаспространённые ошибки оценки производительности .NET-приложений
Распространённые ошибки оценки производительности .NET-приложений
 
Programming c++ (begin-if-else)
Programming c++ (begin-if-else)Programming c++ (begin-if-else)
Programming c++ (begin-if-else)
 
Сложности микробенчмаркинга
Сложности микробенчмаркингаСложности микробенчмаркинга
Сложности микробенчмаркинга
 
разработка серверов и серверных приложений лекция №3
разработка серверов и серверных приложений лекция №3разработка серверов и серверных приложений лекция №3
разработка серверов и серверных приложений лекция №3
 
Евгений Крутько — Опыт внедрения технологий параллельных вычислений для повыш...
Евгений Крутько — Опыт внедрения технологий параллельных вычислений для повыш...Евгений Крутько — Опыт внедрения технологий параллельных вычислений для повыш...
Евгений Крутько — Опыт внедрения технологий параллельных вычислений для повыш...
 
20130429 dynamic c_c++_program_analysis-alexey_samsonov
20130429 dynamic c_c++_program_analysis-alexey_samsonov20130429 dynamic c_c++_program_analysis-alexey_samsonov
20130429 dynamic c_c++_program_analysis-alexey_samsonov
 
C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...
C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...
C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...
 
Сверхоптимизация кода на Python
Сверхоптимизация кода на PythonСверхоптимизация кода на Python
Сверхоптимизация кода на Python
 
Сверхоптимизация кода на Python
Сверхоптимизация кода на PythonСверхоптимизация кода на Python
Сверхоптимизация кода на Python
 
Статический и динамический полиморфизм в C++, Дмитрий Леванов
Статический и динамический полиморфизм в C++, Дмитрий ЛевановСтатический и динамический полиморфизм в C++, Дмитрий Леванов
Статический и динамический полиморфизм в C++, Дмитрий Леванов
 
Опыт разработки статического анализатора кода
Опыт разработки статического анализатора кодаОпыт разработки статического анализатора кода
Опыт разработки статического анализатора кода
 
Intel IPP Samples for Windows - работа над ошибками
Intel IPP Samples for Windows - работа над ошибкамиIntel IPP Samples for Windows - работа над ошибками
Intel IPP Samples for Windows - работа над ошибками
 

More from corehard_by

C++ CoreHard Autumn 2018. Создание пакетов для открытых библиотек через conan...
C++ CoreHard Autumn 2018. Создание пакетов для открытых библиотек через conan...C++ CoreHard Autumn 2018. Создание пакетов для открытых библиотек через conan...
C++ CoreHard Autumn 2018. Создание пакетов для открытых библиотек через conan...corehard_by
 
C++ CoreHard Autumn 2018. Что должен знать каждый C++ программист или Как про...
C++ CoreHard Autumn 2018. Что должен знать каждый C++ программист или Как про...C++ CoreHard Autumn 2018. Что должен знать каждый C++ программист или Как про...
C++ CoreHard Autumn 2018. Что должен знать каждый C++ программист или Как про...corehard_by
 
C++ CoreHard Autumn 2018. Actors vs CSP vs Tasks vs ... - Евгений Охотников
C++ CoreHard Autumn 2018. Actors vs CSP vs Tasks vs ... - Евгений ОхотниковC++ CoreHard Autumn 2018. Actors vs CSP vs Tasks vs ... - Евгений Охотников
C++ CoreHard Autumn 2018. Actors vs CSP vs Tasks vs ... - Евгений Охотниковcorehard_by
 
C++ CoreHard Autumn 2018. Знай свое "железо": иерархия памяти - Александр Титов
C++ CoreHard Autumn 2018. Знай свое "железо": иерархия памяти - Александр ТитовC++ CoreHard Autumn 2018. Знай свое "железо": иерархия памяти - Александр Титов
C++ CoreHard Autumn 2018. Знай свое "железо": иерархия памяти - Александр Титовcorehard_by
 
C++ CoreHard Autumn 2018. Информационная безопасность и разработка ПО - Евген...
C++ CoreHard Autumn 2018. Информационная безопасность и разработка ПО - Евген...C++ CoreHard Autumn 2018. Информационная безопасность и разработка ПО - Евген...
C++ CoreHard Autumn 2018. Информационная безопасность и разработка ПО - Евген...corehard_by
 
C++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья Шишков
C++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья ШишковC++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья Шишков
C++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья Шишковcorehard_by
 
C++ CoreHard Autumn 2018. Ускорение сборки C++ проектов, способы и последстви...
C++ CoreHard Autumn 2018. Ускорение сборки C++ проектов, способы и последстви...C++ CoreHard Autumn 2018. Ускорение сборки C++ проектов, способы и последстви...
C++ CoreHard Autumn 2018. Ускорение сборки C++ проектов, способы и последстви...corehard_by
 
C++ CoreHard Autumn 2018. Метаклассы: воплощаем мечты в реальность - Сергей С...
C++ CoreHard Autumn 2018. Метаклассы: воплощаем мечты в реальность - Сергей С...C++ CoreHard Autumn 2018. Метаклассы: воплощаем мечты в реальность - Сергей С...
C++ CoreHard Autumn 2018. Метаклассы: воплощаем мечты в реальность - Сергей С...corehard_by
 
C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...
C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...
C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...corehard_by
 
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...corehard_by
 
C++ CoreHard Autumn 2018. Обработка списков на C++ в функциональном стиле - В...
C++ CoreHard Autumn 2018. Обработка списков на C++ в функциональном стиле - В...C++ CoreHard Autumn 2018. Обработка списков на C++ в функциональном стиле - В...
C++ CoreHard Autumn 2018. Обработка списков на C++ в функциональном стиле - В...corehard_by
 
C++ Corehard Autumn 2018. Обучаем на Python, применяем на C++ - Павел Филонов
C++ Corehard Autumn 2018. Обучаем на Python, применяем на C++ - Павел ФилоновC++ Corehard Autumn 2018. Обучаем на Python, применяем на C++ - Павел Филонов
C++ Corehard Autumn 2018. Обучаем на Python, применяем на C++ - Павел Филоновcorehard_by
 
C++ CoreHard Autumn 2018. Asynchronous programming with ranges - Ivan Čukić
C++ CoreHard Autumn 2018. Asynchronous programming with ranges - Ivan ČukićC++ CoreHard Autumn 2018. Asynchronous programming with ranges - Ivan Čukić
C++ CoreHard Autumn 2018. Asynchronous programming with ranges - Ivan Čukićcorehard_by
 
C++ CoreHard Autumn 2018. Debug C++ Without Running - Anastasia Kazakova
C++ CoreHard Autumn 2018. Debug C++ Without Running - Anastasia KazakovaC++ CoreHard Autumn 2018. Debug C++ Without Running - Anastasia Kazakova
C++ CoreHard Autumn 2018. Debug C++ Without Running - Anastasia Kazakovacorehard_by
 
C++ CoreHard Autumn 2018. Text Formatting For a Future Range-Based Standard L...
C++ CoreHard Autumn 2018. Text Formatting For a Future Range-Based Standard L...C++ CoreHard Autumn 2018. Text Formatting For a Future Range-Based Standard L...
C++ CoreHard Autumn 2018. Text Formatting For a Future Range-Based Standard L...corehard_by
 
Исключительная модель памяти. Алексей Ткаченко ➠ CoreHard Autumn 2019
Исключительная модель памяти. Алексей Ткаченко ➠ CoreHard Autumn 2019Исключительная модель памяти. Алексей Ткаченко ➠ CoreHard Autumn 2019
Исключительная модель памяти. Алексей Ткаченко ➠ CoreHard Autumn 2019corehard_by
 
Как помочь и как помешать компилятору. Андрей Олейников ➠ CoreHard Autumn 2019
Как помочь и как помешать компилятору. Андрей Олейников ➠  CoreHard Autumn 2019Как помочь и как помешать компилятору. Андрей Олейников ➠  CoreHard Autumn 2019
Как помочь и как помешать компилятору. Андрей Олейников ➠ CoreHard Autumn 2019corehard_by
 
Автоматизируй это. Кирилл Тихонов ➠ CoreHard Autumn 2019
Автоматизируй это. Кирилл Тихонов ➠  CoreHard Autumn 2019Автоматизируй это. Кирилл Тихонов ➠  CoreHard Autumn 2019
Автоматизируй это. Кирилл Тихонов ➠ CoreHard Autumn 2019corehard_by
 
Статичный SQL в С++14. Евгений Захаров ➠ CoreHard Autumn 2019
Статичный SQL в С++14. Евгений Захаров ➠  CoreHard Autumn 2019Статичный SQL в С++14. Евгений Захаров ➠  CoreHard Autumn 2019
Статичный SQL в С++14. Евгений Захаров ➠ CoreHard Autumn 2019corehard_by
 
Как не подавиться большим старым проектом. Юрий Минаев ➠ CoreHard Autumn 2019
Как не подавиться большим старым проектом. Юрий Минаев ➠  CoreHard Autumn 2019Как не подавиться большим старым проектом. Юрий Минаев ➠  CoreHard Autumn 2019
Как не подавиться большим старым проектом. Юрий Минаев ➠ CoreHard Autumn 2019corehard_by
 

More from corehard_by (20)

C++ CoreHard Autumn 2018. Создание пакетов для открытых библиотек через conan...
C++ CoreHard Autumn 2018. Создание пакетов для открытых библиотек через conan...C++ CoreHard Autumn 2018. Создание пакетов для открытых библиотек через conan...
C++ CoreHard Autumn 2018. Создание пакетов для открытых библиотек через conan...
 
C++ CoreHard Autumn 2018. Что должен знать каждый C++ программист или Как про...
C++ CoreHard Autumn 2018. Что должен знать каждый C++ программист или Как про...C++ CoreHard Autumn 2018. Что должен знать каждый C++ программист или Как про...
C++ CoreHard Autumn 2018. Что должен знать каждый C++ программист или Как про...
 
C++ CoreHard Autumn 2018. Actors vs CSP vs Tasks vs ... - Евгений Охотников
C++ CoreHard Autumn 2018. Actors vs CSP vs Tasks vs ... - Евгений ОхотниковC++ CoreHard Autumn 2018. Actors vs CSP vs Tasks vs ... - Евгений Охотников
C++ CoreHard Autumn 2018. Actors vs CSP vs Tasks vs ... - Евгений Охотников
 
C++ CoreHard Autumn 2018. Знай свое "железо": иерархия памяти - Александр Титов
C++ CoreHard Autumn 2018. Знай свое "железо": иерархия памяти - Александр ТитовC++ CoreHard Autumn 2018. Знай свое "железо": иерархия памяти - Александр Титов
C++ CoreHard Autumn 2018. Знай свое "железо": иерархия памяти - Александр Титов
 
C++ CoreHard Autumn 2018. Информационная безопасность и разработка ПО - Евген...
C++ CoreHard Autumn 2018. Информационная безопасность и разработка ПО - Евген...C++ CoreHard Autumn 2018. Информационная безопасность и разработка ПО - Евген...
C++ CoreHard Autumn 2018. Информационная безопасность и разработка ПО - Евген...
 
C++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья Шишков
C++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья ШишковC++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья Шишков
C++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья Шишков
 
C++ CoreHard Autumn 2018. Ускорение сборки C++ проектов, способы и последстви...
C++ CoreHard Autumn 2018. Ускорение сборки C++ проектов, способы и последстви...C++ CoreHard Autumn 2018. Ускорение сборки C++ проектов, способы и последстви...
C++ CoreHard Autumn 2018. Ускорение сборки C++ проектов, способы и последстви...
 
C++ CoreHard Autumn 2018. Метаклассы: воплощаем мечты в реальность - Сергей С...
C++ CoreHard Autumn 2018. Метаклассы: воплощаем мечты в реальность - Сергей С...C++ CoreHard Autumn 2018. Метаклассы: воплощаем мечты в реальность - Сергей С...
C++ CoreHard Autumn 2018. Метаклассы: воплощаем мечты в реальность - Сергей С...
 
C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...
C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...
C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...
 
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...
 
C++ CoreHard Autumn 2018. Обработка списков на C++ в функциональном стиле - В...
C++ CoreHard Autumn 2018. Обработка списков на C++ в функциональном стиле - В...C++ CoreHard Autumn 2018. Обработка списков на C++ в функциональном стиле - В...
C++ CoreHard Autumn 2018. Обработка списков на C++ в функциональном стиле - В...
 
C++ Corehard Autumn 2018. Обучаем на Python, применяем на C++ - Павел Филонов
C++ Corehard Autumn 2018. Обучаем на Python, применяем на C++ - Павел ФилоновC++ Corehard Autumn 2018. Обучаем на Python, применяем на C++ - Павел Филонов
C++ Corehard Autumn 2018. Обучаем на Python, применяем на C++ - Павел Филонов
 
C++ CoreHard Autumn 2018. Asynchronous programming with ranges - Ivan Čukić
C++ CoreHard Autumn 2018. Asynchronous programming with ranges - Ivan ČukićC++ CoreHard Autumn 2018. Asynchronous programming with ranges - Ivan Čukić
C++ CoreHard Autumn 2018. Asynchronous programming with ranges - Ivan Čukić
 
C++ CoreHard Autumn 2018. Debug C++ Without Running - Anastasia Kazakova
C++ CoreHard Autumn 2018. Debug C++ Without Running - Anastasia KazakovaC++ CoreHard Autumn 2018. Debug C++ Without Running - Anastasia Kazakova
C++ CoreHard Autumn 2018. Debug C++ Without Running - Anastasia Kazakova
 
C++ CoreHard Autumn 2018. Text Formatting For a Future Range-Based Standard L...
C++ CoreHard Autumn 2018. Text Formatting For a Future Range-Based Standard L...C++ CoreHard Autumn 2018. Text Formatting For a Future Range-Based Standard L...
C++ CoreHard Autumn 2018. Text Formatting For a Future Range-Based Standard L...
 
Исключительная модель памяти. Алексей Ткаченко ➠ CoreHard Autumn 2019
Исключительная модель памяти. Алексей Ткаченко ➠ CoreHard Autumn 2019Исключительная модель памяти. Алексей Ткаченко ➠ CoreHard Autumn 2019
Исключительная модель памяти. Алексей Ткаченко ➠ CoreHard Autumn 2019
 
Как помочь и как помешать компилятору. Андрей Олейников ➠ CoreHard Autumn 2019
Как помочь и как помешать компилятору. Андрей Олейников ➠  CoreHard Autumn 2019Как помочь и как помешать компилятору. Андрей Олейников ➠  CoreHard Autumn 2019
Как помочь и как помешать компилятору. Андрей Олейников ➠ CoreHard Autumn 2019
 
Автоматизируй это. Кирилл Тихонов ➠ CoreHard Autumn 2019
Автоматизируй это. Кирилл Тихонов ➠  CoreHard Autumn 2019Автоматизируй это. Кирилл Тихонов ➠  CoreHard Autumn 2019
Автоматизируй это. Кирилл Тихонов ➠ CoreHard Autumn 2019
 
Статичный SQL в С++14. Евгений Захаров ➠ CoreHard Autumn 2019
Статичный SQL в С++14. Евгений Захаров ➠  CoreHard Autumn 2019Статичный SQL в С++14. Евгений Захаров ➠  CoreHard Autumn 2019
Статичный SQL в С++14. Евгений Захаров ➠ CoreHard Autumn 2019
 
Как не подавиться большим старым проектом. Юрий Минаев ➠ CoreHard Autumn 2019
Как не подавиться большим старым проектом. Юрий Минаев ➠  CoreHard Autumn 2019Как не подавиться большим старым проектом. Юрий Минаев ➠  CoreHard Autumn 2019
Как не подавиться большим старым проектом. Юрий Минаев ➠ CoreHard Autumn 2019
 

C++ CoreHard Autumn 2018. Полезный constexpr - Антон Полухин

  • 1.
  • 3. Содержание ● Старое и известное ● Старое и незнакомое ● Ближайшее будущее ● Очень далёкое будущее Полезный constexpr C++14 C++26
  • 5. Старое и известное #include <boost/array.hpp> inline unsigned factorial(unsigned n) { return n ? n * factorial(n - 1) : 1; } Полезный constexpr 5 / 67
  • 6. Старое и известное #include <boost/array.hpp> inline unsigned factorial(unsigned n) { return n ? n * factorial(n - 1) : 1; } boost::array<int, factorial(3)> a; Полезный constexpr 6 / 67
  • 7. Старое и известное error: call to non-constexpr function ‘unsigned int factorial(unsigned int)’ boost::array<int, factorial(3)> a; ~~~~~~~~~^~~ error: call to non-constexpr function ‘unsigned int factorial(unsigned int)’ note: in template argument for type ‘long unsigned int’ boost::array<int, factorial(3)> a; Полезный constexpr 7 / 67
  • 8. Старое и известное #include <array> constexpr unsigned factorial(unsigned n) { return n ? n * factorial(n - 1) : 1; } std::array<int, factorial(3)> a; Полезный constexpr 8 / 67
  • 9. Старое и известное (2) #include <stdexcept> int do_something(unsigned n) { constexpr auto i = 7 + 20; // ... return i; } Полезный constexpr 9 / 67
  • 10. Старое и известное (2) #include <stdexcept> int do_something(unsigned n) { constexpr auto i = 7 + 20; // ... return i; } Полезный constexpr 10 / 67
  • 11. Старое и известное (2) #include <stdexcept> constexpr unsigned factorial(unsigned n) { if (n > 10) throw std::out_of_range("n is greater than 10"); return n ? n * factorial(n - 1) : 1; } int do_something(unsigned n) { auto i = factorial(17); // ... return i; } Полезный constexpr 11 / 67
  • 12. Старое и известное (2) #include <stdexcept> constexpr unsigned factorial(unsigned n) { if (n > 10) throw std::out_of_range("n is greater than 10"); return n ? n * factorial(n - 1) : 1; } int do_something(unsigned n) { throw std::out_of_range("n is greater than 10"); } Полезный constexpr 12 / 67
  • 13. Старое и известное (2) #include <stdexcept> constexpr unsigned factorial(unsigned n) { if (n > 10) throw std::out_of_range("n is greater than 10"); return n ? n * factorial(n - 1) : 1; } int do_something(unsigned n) { constexpr auto i = factorial(17); // ... return i; } Полезный constexpr 13 / 67
  • 14. Старое и известное (2) In function ‘int do_something(unsigned int)’: in constexpr expansion of ‘factorial(17)’ error: expression ‘<throw-expression>’ is not a constant expression throw std::out_of_range("n is greater than 10"); Полезный constexpr 14 / 67
  • 16. Статическая инициализация All static initialization strongly happens before any dynamic initialization. int do_something(unsigned n) { static const int i = 17; Полезный constexpr 16 / 67
  • 17. Статическая инициализация All static initialization strongly happens before any dynamic initialization. int do_something(unsigned n) { static const int i = n; Полезный constexpr 17 / 67
  • 18. Статическая инициализация All static initialization strongly happens before any dynamic initialization. int do_something(unsigned n) { static const int i = factorial(7); Полезный constexpr 18 / 67
  • 19. Старое и незнакомое namespace std { class mutex { public: constexpr mutex() noexcept; ~mutex(); mutex(const mutex&) = delete; mutex& operator=(const mutex&) = delete; /*...*/ }; } Полезный constexpr 19 / 67
  • 20. Старое и незнакомое namespace std { class mutex { public: constexpr mutex() noexcept; ~mutex(); mutex(const mutex&) = delete; mutex& operator=(const mutex&) = delete; /*...*/ }; } Полезный constexpr 20 / 67
  • 21. Статическая инициализация A constant initializer for a variable or temporary object o is an initializer whose full-expression is a constant expression, except that if o is an object, such an initializer may also invoke constexpr constructors for o and its subobjects even if those objects are of non-literal class types. [ Note: Such a class may have a non-trivial destructor. — end note ] All static initialization strongly happens before any dynamic initialization. Полезный constexpr 21 / 67
  • 22. Старое и незнакомое // 1.cpp namespace { std::mutex m; } std::mutex& global_mutex() { return m; } // 2.cpp std::vector<int> data = []() { std::lock_guard<std::mutex> l(global_mutex()); // Oops? return some_creepy_api(); }(); Полезный constexpr 22 / 67
  • 23. Старое и незнакомое (2) Полезный constexpr
  • 24. Старое и незнакомое (2) // Bubble-like sort. Anything complex enough will work template <class It> void sort(It first, It last) { /*...*/ } inline int generate(int i) { int a[7] = {3, 7, 4, i, 8, 0, 1}; sort(a + 0, a + 7); return a[0] + a[6]; } int no_constexpr() { return generate(1); } Полезный constexpr 24 / 67
  • 25. Старое и незнакомое (2) no_constexpr(): movabs rax, 30064771075 mov DWORD PTR [rsp-20], 0 lea rdx, [rsp-40] mov QWORD PTR [rsp-40], rax lea rsi, [rdx+28] movabs rax, 4294967300 mov QWORD PTR [rsp-32], rax lea rax, [rsp-40] mov DWORD PTR [rsp-16], 1 add rax, 4 mov DWORD PTR [rsp-24], 8 Полезный constexpr mov rcx, rax .L2: add rax, 4 cmp rax, rsi je .L8 .L6: mov edi, DWORD PTR [rax] mov r8d, DWORD PTR [rdx] cmp edi, r8d jge .L2 mov DWORD PTR [rax], r8d add rax, 4 mov DWORD PTR [rdx], edi cmp rax, rsi jne .L6 .L8: lea rax, [rcx+4] cmp rax, rsi je .L3 mov rdx, rcx mov rcx, rax jmp .L6 .L3: mov eax,DWORD PTR[rsp-16] add eax,DWORD PTR[rsp-40] ret 25 / 67
  • 26. Старое и незнакомое (2) // Bubble-like sort. Anything complex enough will work template <class It> constexpr void sort(It first, It last) { /*...*/ } constexpr int generate(int i) { int a[7] = {3, 7, 4, i, 8, 0, 1}; sort(a + 0, a + 7); return a[0] + a[6]; } int no_constexpr() { return generate(1); } Полезный constexpr 26 / 67
  • 27. Старое и незнакомое (2) no_constexpr(): mov eax, 8 ret Полезный constexpr 27 / 67
  • 29. Анатомия компилятора (упрощённо) Полезный constexpr С++С Fortran ... Middle end Ada Go IR IR Power PCx86 Alpha ...Arm x86_64 29 / 67
  • 30. Анатомия компилятора (без constexpr) Полезный constexpr С++С Fortran ... Middle end Ada Go IR IR :( Power PCx86 Alpha ...Arm x86_64 30 / 67
  • 31. Старое и незнакомое (2) no_constexpr(): movabs rax, 30064771075 mov DWORD PTR [rsp-20], 0 lea rdx, [rsp-40] mov QWORD PTR [rsp-40], rax lea rsi, [rdx+28] movabs rax, 4294967300 mov QWORD PTR [rsp-32], rax lea rax, [rsp-40] mov DWORD PTR [rsp-16], 1 add rax, 4 mov DWORD PTR [rsp-24], 8 Полезный constexpr mov rcx, rax .L2: add rax, 4 cmp rax, rsi je .L8 .L6: mov edi, DWORD PTR [rax] mov r8d, DWORD PTR [rdx] cmp edi, r8d jge .L2 mov DWORD PTR [rax], r8d add rax, 4 mov DWORD PTR [rdx], edi cmp rax, rsi jne .L6 .L8: lea rax, [rcx+4] cmp rax, rsi je .L3 mov rdx, rcx mov rcx, rax jmp .L6 .L3: mov eax,DWORD PTR[rsp-16] add eax,DWORD PTR[rsp-40] ret 31 / 67
  • 32. Анатомия компилятора (constexpr) Полезный constexpr С++С Fortran ... Middle end Ada Go IR IR :) Power PCx86 Alpha ...Arm x86_64 32 / 67
  • 33. Старое и незнакомое (2) no_constexpr(): mov eax, 8 ret Полезный constexpr 33 / 67
  • 34. Старое и незнакомое (3) Полезный constexpr
  • 35. Старое и незнакомое (3) #include <stdexcept> constexpr int factorial(int n) { return n ? n * factorial(n - 1) : 1; } int do_something(unsigned n) { constexpr auto i = factorial(27); // ... return i; } Полезный constexpr 35 / 67
  • 36. Старое и незнакомое (3) main.cpp: In function ‘int do_something(unsigned int)’: main.cpp:200:33: in constexpr expansion of ‘factorial(27)’ main.cpp:197:29: in constexpr expansion of ‘factorial((n + -1))’ main.cpp:197:29: in constexpr expansion of ‘factorial((n + -1))’ <...> main.cpp:197:29: in constexpr expansion of ‘factorial((n + -1))’ main.cpp:197:29: in constexpr expansion of ‘factorial((n + -1))’ main.cpp:197:29: in constexpr expansion of ‘factorial((n + -1))’ main.cpp:200:36: error: overflow in constant expression [-fpermissive] constexpr auto i = factorial(27); ^ Полезный constexpr 36 / 67
  • 38. Constexpr: * Позволяет использовать функции для вычисления констант * «Заставляет» вычислять константы * Позволяет статически инициализировать объекты * Оптимизирует код * Позволяет проверять на UB Полезный constexpr 38 / 67
  • 40. Constexpr new А давайте разрешим вызывать new в constexpr функциях, если в этой же constexpr функции память освобождается. Ну и деструкторы разрешим делать constexpr: constexpr auto precompute_series(int n, int i) { std::vector<int> v(n); /*...*/ return v[i]; } Полезный constexpr 40 / 67
  • 41. Constexpr new А давайте будем память выделенную через new в constexpr функциях записывать прям в бинарник и не вызывать деструктор для объекта [*] (прям как при константной инициализации): constexpr auto precompute_whole_series(int n) { std::vector<int> v(n); /*...*/ return v; } [*] - есть тонкости Полезный constexpr 41 / 67
  • 42. Constexpr new А давайте будем память выделенную через new в constexpr функциях записывать прям в бинарник и не вызывать деструктор для объекта [*] (прям как при константной инициализации): const std::string we_need_this = "Something usefull"; const std::string time_format = "YYYY-MM-DDTHH:MM:SS"; Полезный constexpr 42 / 67
  • 44. Регулярки Регулярки медленно инициализаируются: bool is_valid_mail(std::string_view mail) { // ~260 sµ static const std::regex mail_regex(R"((?:(?:[^<>()[].,;:s@"]+ (?:.[^<>()[].,;:s@"]+)*)|".+")@(?:(?:[^<>()[].,;:s@"]+.)+ [^<>()[].,;:s@"]{2,}))"); return std::regex_match( std::cbegin(mail), std::cend(mail), mail_regex ); }Полезный constexpr 44 / 67
  • 45. Constexpr regex Ой, смотрите, мы же теперь можем сделать constexpr std::regex: bool is_valid_mail(std::string_view mail) { // Проинициализируется на этапе компиляции static const std::regex mail_regex(/*...*/); return std::regex_match( std::cbegin(mail), std::cend(mail), mail_regex ); } Полезный constexpr 45 / 67
  • 46. Constexpr boyer_moore_ho rspool_searcher std::boyer_moore_horspool_searcher — иногда ищет быстро, а вот конструируется медленно. --------------------------------------------------- Benchmark Time CPU Iterations --------------------------------------------------- BM_bmh_construction 118 ns 118 ns 4644219 BM_bmh_construction_huge 184 ns 184 ns 3779484 BM_bmh_apply 34 ns 34 ns 20578297 BM_bmh_apply_huge 73 ns 73 ns 9311461 Можно будет сделать constexpr конструктор, и наслаждаться конструированием на этапе компиляции, а не на рантайме. Полезный constexpr 46 / 67
  • 48. Рефлексия struct User { std::string name; unsigned age; [[orm "id"]] unsigned uuid; }; Полезный constexpr 48 / 67
  • 49. Рефлексия // Синтаксис изменится! template <class Db, class Data> void fill_from_db(Db& db, Data& d) { auto it = $d.fields.name("id") || $d.fields.attributes("orm "id"").fields()[0]; db.start(*it); for (auto field: $d.fields()) { constexpr std::string name { field.attribute("orm") ? field.attribute("orm") : field.name() }; db[name] >> field; } } Полезный constexpr 49 / 67
  • 50. Рефлексия // Синтаксис изменится! template <class Db, class Data> void fill_from_db(Db& db, Data& d) { // User auto it = $d.fields.name("id") || $d.fields.attributes("orm "id"").fields()[0]; db.start(*it); for (auto field: $d.fields()) { constexpr std::string name { field.attribute("orm") ? field.attribute("orm") : field.name() }; db[name] >> field; } } Полезный constexpr 50 / 67
  • 51. Рефлексия // Синтаксис изменится! template <class Db, class Data> void fill_from_db(Db& db, Data& d) { // User auto it = $d.fields.name("id") || $d.fields.attributes("orm "id"").fields()[0]; db.start(*it); // d.uuid for (auto field: $d.fields()) { constexpr std::string name { field.attribute("orm") ? field.attribute("orm") : field.name() }; db[name] >> field; } } Полезный constexpr 51 / 67
  • 52. Рефлексия // Синтаксис изменится! template <class Db, class Data> void fill_from_db(Db& db, Data& d) { // User auto it = $d.fields.name("id") || $d.fields.attributes("orm "id"").fields()[0]; db.start(*it); // d.uuid for (auto field: $d.fields()) { constexpr std::string name { field.attribute("orm") ? field.attribute("orm") : field.name() }; db[name] >> field; // «age», «name» => d.age, d.name } } Полезный constexpr 52 / 67
  • 53. Рефлексия // Синтаксис изменится! template <class Db, class Data> void fill_from_db(Db& db, Data& d) { auto it = $d.fields.name("id") || $d.fields.attributes("orm "id"").fields()[0]; db.start(*it); for (auto field: $d.fields()) { // constexpr std::vector<field> constexpr std::string name { field.attribute("orm") ? field.attribute("orm") : field.name() }; db[name] >> field; } } Полезный constexpr 53 / 67
  • 54. Рефлексия template <class Db> void fill_from_db(Db& db, User& d) { db.start(d.uuid); db["age"] >> d.age; db["name"] >> d.name; } Полезный constexpr 54 / 67
  • 55. Рефлексия int main() { Mongo m; User u{.uuid=42}; fill_from_db(m, u) std::cout << "User with id = 42 is " << u.name; } Полезный constexpr 55 / 67
  • 57. Рефлексия и проблемы // Синтаксис изменится! template <class Db, class Data> void fill_from_db(Db& db, class Data& d) { auto it = $d.fields.name("id") || $d.fields.attributes("orm "id"").fields()[0]; db.start(*it); for (auto field: $d.fields()) { // constexpr std::vector<field> constexpr std::string name { field.attribute("orm") ? field.attribute("orm") : field.name() }; db[name] >> field; } } Полезный constexpr 57 / 67
  • 58. constexpr функции Полезный constexpr С++С Fortran ... Middle end Ada Go IR IR Power PCx86 Alpha ...Arm x86_64 Smth.cpp 58 / 67
  • 59. constexpr! функции Полезный constexpr С++С Fortran ... Middle end Ada Go IR IR Power PCx86 Alpha ...Arm x86_64 Smth.cpp 59 / 67
  • 61. Метаклассы $orm User { std::string name; unsigned age; [[orm "id"]] unsigned uuid; }; Полезный constexpr 61 / 67
  • 62. Метаклассы $orm User { std::string name; unsigned age; [[orm "id"]] unsigned uuid; }; Полезный constexpr 62 / 67
  • 63. Метаклассы int main() { Mongo m; User u(42, m); std::cout << "User with id = 42 is " << u.name(); } Полезный constexpr 63 / 67
  • 64. Метаклассы $class orm { for (auto field: $this->fields()) { $"auto " + field.name() + "() const { return m_" + field.name() + "; }"; $"void set_" + field.name() + "(auto v) { m_" + field.name() + "=std::move(v); }"; field.make_private().set_name("m_" + field.name()); } $"template <class Db>" + $this->name() + $"(unsigned id, Db& db) : m_uuid(id) { " + "fill_from_db(db, *this);" + "}"; }; Полезный constexpr 64 / 67
  • 65. Метаклассы class User { std::string m_name; unsigned m_age; unsigned m_uuid; public: auto name() const { return m_name; } auto age() const { return m_age; } auto uuid() const { return m_uuid; } // ... template <class Db> User(unsigned id, Db& db) : m_uuid(id) { fill_from_db(db, *this); } }; Полезный constexpr 65 / 67
  • 67. Полухин Антон Старший разработчик Yandex.Taxi antoshkka@yandex-team.ru antoshkka@gmail.com https://github.com/apolukhin https://stdcpp.ru/