В лекции подробно рассмотрены тонкие моменты языка JavaScript, с которыми часто возникают основные проблемы. Наглядные примеры и рецепты помогают лучше понять его особенности.
Павел Беликов, Как избежать ошибок, используя современный C++Sergey Platonov
Одной из проблем C++ является большое количество конструкций, поведение которых не определено или просто неожиданно для программиста. С такими ошибками мы часто сталкиваемся при разработке статического анализатора кода. Но, как известно, лучше всего находить ошибки ещё на этапе компиляции. На этом докладе мы поговорим о том, какие техники из современного C++ позволяют писать не только более простой и выразительный, но и безопасный код. Вы увидите ошибки в коде различных Open Source проектов и узнаете, как можно их избежать, используя новые стандарты
Объектно-Ориентированное Программирование на C++, Лекции 3 и 4 Dima Dzuba
Описываются возможности C++ по работе с наследованием (virtual, override, final). Описываются механизмы работы с константными переменными и методами (const, mutable, constexpr). Описываются возможности по перегрузке операторов (operator).
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионаловSergey Platonov
В докладе перед нами откроется великолепный мир велосипедов и устаревших технологий, которые люди продолжают переносить в новые проекты и повсеместно использовать. Мы поговорим о:
Copy-On-Write
разработке без оглядки на готовые решения и к чему это приводит
force inline
оптимизациях, которые отлично себя показывают на бенчмарках и плохо себя ведут в реальной жизни
бездумно отключаемых оптимизациях компилятора
тонкостях стандартной библиотеки для повседневного использования
супер качественном велосипедостроении
В лекции подробно рассмотрены тонкие моменты языка JavaScript, с которыми часто возникают основные проблемы. Наглядные примеры и рецепты помогают лучше понять его особенности.
Павел Беликов, Как избежать ошибок, используя современный C++Sergey Platonov
Одной из проблем C++ является большое количество конструкций, поведение которых не определено или просто неожиданно для программиста. С такими ошибками мы часто сталкиваемся при разработке статического анализатора кода. Но, как известно, лучше всего находить ошибки ещё на этапе компиляции. На этом докладе мы поговорим о том, какие техники из современного C++ позволяют писать не только более простой и выразительный, но и безопасный код. Вы увидите ошибки в коде различных Open Source проектов и узнаете, как можно их избежать, используя новые стандарты
Объектно-Ориентированное Программирование на C++, Лекции 3 и 4 Dima Dzuba
Описываются возможности C++ по работе с наследованием (virtual, override, final). Описываются механизмы работы с константными переменными и методами (const, mutable, constexpr). Описываются возможности по перегрузке операторов (operator).
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионаловSergey Platonov
В докладе перед нами откроется великолепный мир велосипедов и устаревших технологий, которые люди продолжают переносить в новые проекты и повсеместно использовать. Мы поговорим о:
Copy-On-Write
разработке без оглядки на готовые решения и к чему это приводит
force inline
оптимизациях, которые отлично себя показывают на бенчмарках и плохо себя ведут в реальной жизни
бездумно отключаемых оптимизациях компилятора
тонкостях стандартной библиотеки для повседневного использования
супер качественном велосипедостроении
Обобщенное программирование в C++ или как сделать свою жизнь проще через стра...corehard_by
Обобщенное программирование - это подход к программированию, когда алгоритм пишется без указания конкретных типов данных. Используя данный подход можно значительно увеличить количество повторно используемого кода. В C++ данный подход реализуется за счет механизма шаблонов. В данном докладе рассмотрим некоторые возможности по обобщенному программированию, которые предоставляет C++. На конкретных примерах рассмотрим, как они могут упростить нам жизнь и с какими трудностями приходится сталкиваться при их использовании.
Григорий Демченко, Асинхронность и неблокирующая синхронизацияSergey Platonov
Практика показывает, что использование подхода, основанного на колбеках для асинхронного программирования обычно не является удобным и подвержено различным ошибкам. Для упрощения написания и поддержки сложных асинхронных программ можно использовать несколько иной подход: использовать сопрограммы для переключения контекста на время ожидания события. Такой подход позволяет реализовать интересные неблокирующие примитивы, включая неблокирующее сетевое взаимодействие, неблокирующие мьютексы, а также удобное переключение между различными пулами потоков для разнесения выполнения задач, которые требуют различные ресурсы.
В докладе рассказывается об особенностях подхода к dependence injections в C++. Посмотрим какие подходы, в чем их плюсы и минусы. Также затрагивается тема Inversion of Control контейнеров.
Догнать и перегнать boost::lexical_castRoman Orlov
Разбор нестандартной реализации преобразования целого числа в строку без использования циклов и рекурсивных вызовов времени исполнения - только рекурсия на этапе компиляции
В рамках данного выступления вас ждут:
* рассказ о полезных и интересных вещах из Boost
* новости с передовиц разработки Boost и о новинках ожидаемых в следующих версиях
* что из Boost готовится к переезду в новый стандарт С++
* как экспериментировать с Boost, имея под рукой только браузер
* что людям не нравится в Boost и как с этими людьми бороться (-:
Метапрограммирование в C++11/14 и C++17. Новые инструменты - новые проблемы.Roman Orlov
В докладе будут затронуты принципиальные вопросы — зачем нам программировать на шаблонах, как мы это делаем в C++11/14 и как будем это делать в C++17. Проведем параллель с функциональными языками (привет Haskell!). На примере реального кода разберем fold-expressions и увидим, чем опасен constexpr-if. А также взглянем на метапрограммирование в стиле C++11/14 и C++17 глазами компилятора.
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++ Sergey Platonov
В последнее время в промышленной разработке ПО особую популярность обретают Domain-Specific Lanugages (DSL). Они драматически упрощают разработку и дают возможность “программировать” не только программистам, но и пользователям прикладных программ.
В своем докладе я расскажу об опыте использования DSL применительно к С++, причем упор будет сделан на производительность кода DSL, и его мгновенную “встраиваемость” в запущенную программу путем компиляции DSL-кода в нативный код с помощью инструментария LLVM.
Рассмотрены известные автору подходы к реализации как lock-free, так и fine-grained lock-based set/map: хеш-таблицы, деревья. Что из подходов STL может быть реализовано в lock-free манере, а что принципиально нет. Подводные камни lock-free и их нейтрализация.
В докладе будут сделаны попытки ответить на вопросы, какой тип скрывается под маской auto, почему T&& не всегда rvalue, и почему move ничего не двигает.
Евгений Зуев, С++ в России: Стандарт языка и его реализацияPlatonov Sergey
Доклад посвящён различным аспектам компилятора С++, созданного с участием автора. В выступлении рассказывается о продвинутой архитектуре компилятора, основных проектных решениях, а также обсуждаются особенности входного языка, повлиявшие на реализацию компилятора.
C++ богат различными инструментами, при разработке на C++ используется множество различных подходов. Но можно ли пользоваться ими во всех случаях или бывают ситуации, когда стоит воздержаться или ограничить их использование?
В докладе пойдет речь о том, какие существуют ограничения при разработке браузера и откуда они взялись. Почему мы живем без исключений или RTTI, к чему это ведет. Как мы используем стандартную библиотеку и сторонние модули.
Дракон в мешке: от LLVM к C++ и проблемам неопределенного поведенияPlatonov Sergey
В этом докладе Дмитрий кратко рассказывает о таком звере, как LLVM, о котором много кто слышал, но немногие щупали.
Что такое компилятор на самом деле? Как происходит компиляция программы, как работают оптимизации и, наконец, откуда берется неопределенное поведение в детерменированных программах на C++?
Клиент-сайд изобилует кучей различных транспортов, и зачастую непонятно, какой взять для решения той или иной задачи. В данной лекции рассказывается об особенности каждого транспорта и области применимости.
Обобщенное программирование в C++ или как сделать свою жизнь проще через стра...corehard_by
Обобщенное программирование - это подход к программированию, когда алгоритм пишется без указания конкретных типов данных. Используя данный подход можно значительно увеличить количество повторно используемого кода. В C++ данный подход реализуется за счет механизма шаблонов. В данном докладе рассмотрим некоторые возможности по обобщенному программированию, которые предоставляет C++. На конкретных примерах рассмотрим, как они могут упростить нам жизнь и с какими трудностями приходится сталкиваться при их использовании.
Григорий Демченко, Асинхронность и неблокирующая синхронизацияSergey Platonov
Практика показывает, что использование подхода, основанного на колбеках для асинхронного программирования обычно не является удобным и подвержено различным ошибкам. Для упрощения написания и поддержки сложных асинхронных программ можно использовать несколько иной подход: использовать сопрограммы для переключения контекста на время ожидания события. Такой подход позволяет реализовать интересные неблокирующие примитивы, включая неблокирующее сетевое взаимодействие, неблокирующие мьютексы, а также удобное переключение между различными пулами потоков для разнесения выполнения задач, которые требуют различные ресурсы.
В докладе рассказывается об особенностях подхода к dependence injections в C++. Посмотрим какие подходы, в чем их плюсы и минусы. Также затрагивается тема Inversion of Control контейнеров.
Догнать и перегнать boost::lexical_castRoman Orlov
Разбор нестандартной реализации преобразования целого числа в строку без использования циклов и рекурсивных вызовов времени исполнения - только рекурсия на этапе компиляции
В рамках данного выступления вас ждут:
* рассказ о полезных и интересных вещах из Boost
* новости с передовиц разработки Boost и о новинках ожидаемых в следующих версиях
* что из Boost готовится к переезду в новый стандарт С++
* как экспериментировать с Boost, имея под рукой только браузер
* что людям не нравится в Boost и как с этими людьми бороться (-:
Метапрограммирование в C++11/14 и C++17. Новые инструменты - новые проблемы.Roman Orlov
В докладе будут затронуты принципиальные вопросы — зачем нам программировать на шаблонах, как мы это делаем в C++11/14 и как будем это делать в C++17. Проведем параллель с функциональными языками (привет Haskell!). На примере реального кода разберем fold-expressions и увидим, чем опасен constexpr-if. А также взглянем на метапрограммирование в стиле C++11/14 и C++17 глазами компилятора.
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++ Sergey Platonov
В последнее время в промышленной разработке ПО особую популярность обретают Domain-Specific Lanugages (DSL). Они драматически упрощают разработку и дают возможность “программировать” не только программистам, но и пользователям прикладных программ.
В своем докладе я расскажу об опыте использования DSL применительно к С++, причем упор будет сделан на производительность кода DSL, и его мгновенную “встраиваемость” в запущенную программу путем компиляции DSL-кода в нативный код с помощью инструментария LLVM.
Рассмотрены известные автору подходы к реализации как lock-free, так и fine-grained lock-based set/map: хеш-таблицы, деревья. Что из подходов STL может быть реализовано в lock-free манере, а что принципиально нет. Подводные камни lock-free и их нейтрализация.
В докладе будут сделаны попытки ответить на вопросы, какой тип скрывается под маской auto, почему T&& не всегда rvalue, и почему move ничего не двигает.
Евгений Зуев, С++ в России: Стандарт языка и его реализацияPlatonov Sergey
Доклад посвящён различным аспектам компилятора С++, созданного с участием автора. В выступлении рассказывается о продвинутой архитектуре компилятора, основных проектных решениях, а также обсуждаются особенности входного языка, повлиявшие на реализацию компилятора.
C++ богат различными инструментами, при разработке на C++ используется множество различных подходов. Но можно ли пользоваться ими во всех случаях или бывают ситуации, когда стоит воздержаться или ограничить их использование?
В докладе пойдет речь о том, какие существуют ограничения при разработке браузера и откуда они взялись. Почему мы живем без исключений или RTTI, к чему это ведет. Как мы используем стандартную библиотеку и сторонние модули.
Дракон в мешке: от LLVM к C++ и проблемам неопределенного поведенияPlatonov Sergey
В этом докладе Дмитрий кратко рассказывает о таком звере, как LLVM, о котором много кто слышал, но немногие щупали.
Что такое компилятор на самом деле? Как происходит компиляция программы, как работают оптимизации и, наконец, откуда берется неопределенное поведение в детерменированных программах на C++?
Клиент-сайд изобилует кучей различных транспортов, и зачастую непонятно, какой взять для решения той или иной задачи. В данной лекции рассказывается об особенности каждого транспорта и области применимости.
Функциональное программирование с использованием библиотеки fp-ts | Odessa Fr...OdessaFrontend
Дмитрий Ховрич рассказывает как использовать строгую типизацию TypeScript и писать надёжный код в функциональном стиле. А также делится знаниями как использовать функторы и монады в ежедневной фронтенд разработке.
Olexandra Dmytrenko
QA Automating at EPAM Systems
I'll show you how to switch from writing standard code using good old Java7 into writing it using functional way presented in Java8. The training is counted on beginners in the subject who like discovering the new horizons or for those who want to become more firm in using the new lambda features.
2. 2
Полиморфизм
Полиморфизм – возможность принимать множество
форм, иметь разный смысл в зависимости от ситуации
Полиморфизм в языке С++ позволяет программисту:
создавать функции, имеющие одинаковые имена, но разные наборы
аргументов (перегрузка функций)
определять действие операторов для новых АТД (перегрузка операторов)
3. 3
Перегрузка функций
Перегрузка функций – использование одного имени для
функций, выполняющих действия с аргументами разных
типов
void print(double d);
void print(Lens l);
void print(double x, double y);
Если бы не было перегрузки функций
print_int(int i);
print_char(char c);
print_Lens(Lens l);
4. 4
Поиск подходящей перегруженной
функции
Последовательность поиска
проверка точного соответствия типов
попытка “повышения типов” (short -> int, float -> double ...)
попытка стандартных преобразований (int -> double, double -> int, ...)
преобразование явно задаваемое программистом
Автоматическое преобразование типов
bool, char повышается до int
int < long < float < double
Явное преобразование типов
(тип) выражение
тип (выражение)
Возвращаемые типы не участвуют в определении какую из
перегруженных функций вызвать.
float sqrt(float);
float sqrt(double);
double sqrt(double);
5. 5
Преобразование типов при
помощи конструктора
// преобразование из double в Complex
Complex::Complex(double x)
{
m_re=x;
m_im=0.;
}
// пример использования
Complex x;
x=Complex(3.14);
// оператор explicit запрещает неявный вызов конструктора для
преобразования типа
class Matrix
{
public:
explicit Matrix(int size);
}
Matrix::Matrix(int size)
{
m_data=new double[size*size];
}
6. 6
Аргументы функции по умолчанию
описание полного конструктора с параметрами по умолчанию
Lens(double r1, double r2, double D=0., double d=0., double n=1.);
реализация полного конструктора с параметрами по умолчанию
Lens::Lens(double r1, double r2, double D, double d, double n)
: m_r1(r1) , m_r2(r2) , m_d(d) , m_D(D) , m_n(n)
{ }
аргументы по умолчанию должны быть указаны в конце списка аргументов и
подряд
Lens lens(100.,-100.); // r1=100 r2=-100 D=0 d=0 n=1
Lens lens(100.,-100.,50.); // r1=100 r2=-100 D=50 d=0 n=1
Lens lens(100.,-100.,50.,10.); // r1=100 r2=-100 D=50 d=10 n=1
Lens lens(100.,-100.,50.,10.,1.5);// r1=100 r2=-100 D=0 d=10 n=1.5
Lens lens(100.,-100.,1.5); // r1=100 r2=-100 D=1.5 d=0 n=1
11. 11
Перегрузка оператора
присваивания
Правила перегрузки оператора присваивания
аргументом должна быть неизменяемая ссылка на экземпляр данного класса
перед присваиванием необходимо сделать проверку на присваивание самому себе
присваивание должно быть поэлементное
оператор должен возвращать ссылку на самого себя
// оператор присваивания
Complex& Complex::operator=(const Complex& other)
{
if(this != &other)
{
m_re=other.m_re;
m_im=other.m_im;
}
return *this;
}
// пример использования
Complex x, y, z;
x=y=z=1;
12. 12
Перегрузка операторов с
присваиванием
Правила перегрузки с присваиванием
аргументом должна быть неизменяемая ссылка на экземпляр данного
класса
оператор должен возвращать ссылку на самого себя
// умножение с присваиванием
Complex& Complex::operator*=(const Complex& other)
{
Complex temp(*this);
m_re=temp.m_re*other.m_re - temp.m_im*other.m_im;
m_im=temp.m_re*other.m_im + temp.m_im*other.m_re;
return *this;
}
// пример использования
Complex x, y;
x*=y;
13. 13
Перегрузка преобразования типов
// преобразование типа Complex в double
Complex::operator double() const
{
return (m_re*m_re-m_im*m_im);
}
// пример использования
Complex x;
double y;
y=double(x);
14. 14
Перегрузка индексирования
// индексирование
double& matrix::operator() (int i, int j)
{
return (p[i][j]); // или p[i*size+j];
}
// пример использования
matrix x;
double y;
y=matrix(1,1); // доступ к элементу (1,1)
15. 15
Перегрузка операторов
ввода/вывода
Оформляются как дружественные функции класса
// описание
friend ostream& operator<< (ostream& out, const Complex& x);
friend istream& operator>> (istream& out, Complex& x);
// объявление
ostream& operator<< (ostream& out, const Complex& x)
{
return (out<<”(“<<x.m_re<<”,”<<x.m_im<<”)”);
}
// пример использования
Complex x;
cout<<x<<endl;
16. 16
Неперегружаемые операторы
Оператор ::
левый и правый операнд являются не значениями, а именем
Оператор .
правый операнд является именем
Оператор .*
правый операнд является именем
Оператор ? :
арифметический оператор имеет специфическую семантику
Оператор new
операнд является именем, кроме того выполняет небезопасную процедуру
Оператор delete
не используется без new, кроме того выполняет небезопасную процедуру
Нельзя определить новые операторы См. пример программы
17. 17
Параметрический полиморфизм
Параметрический полиморфизм позволяет многократно
использовать один и тот же код применительно к разным
типам
тип указывается как параметр функции или класса
Шаблоны (templates) – средство для реализаций
параметризированных классов и функций на языке С++
18. 18
Шаблоны функций
void swap(int& x, int& y)
{
int temp;
temp=x;
x=y;
y=temp;
}
// использование шаблона
double x=1, y=5;
swap<double> (x, y); // TYPE заменяется на double
Инстанцирование – генерация функции по шаблону и ее аргументу
template<class TYPE>
void swap(TYPE& x, TYPE& y)
{
TYPE temp;
temp=x;
x=y;
y=temp;
}
См. пример программы
19. 19
Шаблоны функций с несколькими
параметрами
// пример 1
template<class PAR1, class PAR2>
bool transform(PAR1 x, PAR2& y)
{
if(sizeof(y) < sizeof(x))
{
return false;
}
y=(PAR2)x;
return true;
}
// пример 2
template<class PAR, int n>
PAR factorial()
{
PAR sum=1;
i=1;
while(i<=n)
{
sum*=i;
i++;
}
return sum;
}
20. 20
Пример шаблона класса
template <class PAR>
class Complex
{
protected:
PAR m_re, m_im; //вещественная и мнимая часть
public:
Complex(); // конструктор по умолчанию
Complex(PAR re, PAR im=PAR(0)); // полный конструктор
Complex(const Complex<PAR>& other); // конструктор копирования
// получение параметров комплексного числа
PAR GetRe() const;
PAR GetIm() const;
// перегруженные операторы
Complex<PAR> operator*(const Complex<PAR>& other) const;
Complex<PAR>& operator=(const Complex<PAR>& other);
Complex<PAR> operator~() const;
};
23. 23
Объекты-функции
Объекты-функции – объекты, у которых перегружен
оператор вызова функций operator()
Объекты-функции в <functional> :
plus – сложение
minus – вычитание
multiplies – умножение
divides – деление
modulus – деление по модулю
negate – отрицание
24. 24
Стандартный объект-функция
negate
vector<int> v;
vector<int>::iterator it=v.begin();
while(it != v.end())
{
*it = -(*it);
it++;
}
// то же самое с использование объекта-функции negate
transform(v.begin(),v.end(), v.begin(), negate<int>());
// вывод на экран
copy(v.begin(), v.end(), ostream_iterator<int>(cout, " "));
// чтение из стандартного потока
copy(istream_iterator<int>(cin), istream_iterator<int>(),
back_inserter(v));
25. 25
Создание объекта-функции Rand
template <class PAR>
// параметры – тип данных и возвращаемое значение оператора ()
class Rand : public unary_function<PAR, void>
{
PAR m_min, m_max;
public:
Rand(PAR min, PAR max)
: m_min(min), m_max(max)
{ }
void operator() (PAR& i)
{
i=(PAR)(rand()*(m_max-m_min))/RAND_MAX+m_min;
}
};
// использование объекта-функции Rand
for_each(v.begin(), v.end(), Rand<int>(-10,10));
26. 26
Преобразование бинарной
функции в унарную
Унарная функция – участвует один элемент (отрицание)
Бинарная функция – участвуют два элемента (сложение, умножение, ...)
Умножение каждого элемента на 2 – как?
transform(v.begin(), v.end(), v.begin(), multiplies<int>());
Функция binder2nd – преобразует бинарную функцию в унарную, и принимает второй
аргумент как параметр бинарной функции (<functional>)
// умножение каждого элемента на 2
transform (v.begin(), v.end(), v.begin(),
bind2nd(multiplies<int>(), 2));
См. пример программы
27. 27
Предикаты
Предикаты позволяют без изменения шаблона изменять
критерии сравнения элементов контейнера и другие
подобные действия.
объект-функция возвращает значение bool
Объекты-функции в <functional>
equal_to бинарный предикат равенства
not_equal_to бинарный предикат неравенства
greater бинарный предикат >
less бинарный предикат < (используется по умолчанию)
greater_equal бинарный предикат >=
less_equal бинарный предикат <=
logical_and бинарный предикат И
logical_or бинарный предикат ИЛИ
logical_not унарный предикат НЕ
29. 29
Создание предиката InRange
// параметры – тип данных и возвращаемое значение оператора ()
class InRange : public unary_function<int, bool>
{
int m_left, m_right;
public:
InRange(int left, int right)
: m_left(left), m_right(right)
{}
bool operator() (const int& i)
{
return (i>m_left && i<m_right);
}
};
// использование InRange
vector<int> v(10);
for_each(v.begin(), v.end(), Rand<int>(0,10000));
cout << count_if(v.begin(), v.end(), InRange(1000,10000));
См. пример программы