понедельник, 15 октября 2018 г.

Отчет о CPPCON 2018 (часть 1)

В сентябре завершилась одна из самых крупных конференций для C++ разработчиков cppcon 2018. На этот раз она проходила в Бельвью. В ней приняли учасие такие гуру своего дела как Андрей Александреску, Скот Мейерс, Бьёрн Страуструп, Герб Саттер и другие, чьи имена у всех на слуху, и книги которых многие конечно читали.
Из того, что показалось интересным мне, я бы выделил следующие выступления:

1. Louis Dionne "Compile-time programming and reflection in C++20 and beyond" 


Доклад получился познавательным и интересным. Louis Dionne периодически участвует в разного рода конференциях, выступая преимущественно с докладами по шаблонам, метапрограммированию в С++, Boost.Hana и другим связанным темам, делая при этом всегда упор на новые стандарты С++.
Автор много рассказывал про constexpr, про развитие возможностей, который предоставляет этот инструмент в разных редакциях стандарта. Всё идет к тому, чтобы постепенно увеличивать и наращивать доступные программисту средства языка, которые можно использовать в купе с constexpr. Так, например, в C++ 17 возможность использования if constexpr позволяет целиком заменить некоторые сложные блоки SFINAE. Таким образом в связи с перспективами дальнейшего развития constexpr, его следует активно использовать там, где это необходимо.
Также автор рассказывал про рефлексию типов, которая будет доступна в будущих стандартах языка. Концепция рефлексии в С++ очень напоминает рефлексию в .Net, которая доступна всем C# девелоперам с ранних версий .Net. К примеру, можно будет написать универсальный метод вывода в поток названия элемента любого енума.

2. Kate Gregory "Simplicity: Not Just For Beginners"


Простое и незамысловатое выступление на тему совершенного кода. Не стоит ожидать от этого доклада получение большого объема новых знаний, но в целом посмотреть интересно, чтобы прочистить голову на тему красивого кода, к чему следует стремиться при написании кода, на тему того, какой код можно считать красивым, и в чем его преимущества. После просмотра сразу появилось желание перечитать книгу Роберта Мартина "Чистый код".

3. Bjarne Stroustrup "Concepts: The Future of Generic Programming (the future is here)"


Здесь Страуструп больше часа рассказывал про концепты, которые нас ожидают в С++ 20. На мой взгляд доклад можно было бы сделать хотя бы раза в полтора короче. Но в целом посмотреть однозначно стоит. Концепты уже точно появятся в С++ 20, и судя по тому, как видит развитие языка его создатель, у концептов большое будущее. Поэтому вполне логично инвестировать свое время в изучении данного средства языка уже сейчас с тем, чтобы применять его по возможности на практике в дальнейшем.
Из примера на вики концепты могут быть объявлены как-то так:
template <class T>
concept bool EqualityComparable() {
    return requires(T a, T b) {
        {a == b} -> Boolean; // Boolean is the concept defining a type usable in boolean context
        {a != b} -> Boolean;
    };
}
С одной стороны это просто дополнительное ограничение для шаблонного параметра. То же самое можно было бы получить с использованием std::enable_if и SFINAE. Но с другой использование концептов делает код гораздо более читаемым и лаконичным.
Кроме того, как обещает Страуструп, использование концептов значительно сократит время компиляции по сравнению с использованием стандартных средств обобщенного программирования.

Читайте продолжение отчета во второй части. 

пятница, 7 сентября 2018 г.

Перегрузка и частичная специализация функций

Возьмем следующий пример кода:
template <typename T> void foo(T); // строка 1
template <typename T> void foo(T*); // строка 2
template <>           void foo<int>(int*); // строка 3
Здесь в строке 1 мы объявляем шаблон функции с одним параметром T.
В строке 2 перегружаем нашу шаблонную функцию.
В строке 3 выполняем полную специализацию шаблонной функции, а именно ее перегруженного варианта в строке 2.

Теперь попробуем переставить строки 2 и 3 местами:
template <typename T> void foo(T); // строка 1
template <>           void foo<int*>(int*); // строка 2
template <typename T> void foo(T*); // строка 3
В обоих случаях будем вызывать нашу функцию так:
foo(new int);
Вопреки ожиданиям столь незначительное изменение меняет поведение программы.
Дело в том, что теперь специализация шаблонной функции в строке 2 относится к шаблонной функции в строке 1.

Далее в игру вступает та особенность компилятора, при которой он сначала выбирает наиболее подходящую перегрузку функции, а затем для данной перегрузки еще выбирает специализацию.
В первом фрагменте кода, компилятор сначала выбирает подходящую перегрузку функции, что для new int очевидно соответствует строке 2, а затем выбирает подходящую специализацию, и в итоге вызывается функция из строки 3:
template <>           void foo<int>(int*); // строка 3
Во втором фрагменте кода, компилятор всё также сначала выбирает перегрузку функции, это строка 3, потом смотрит, если ли специализации, но специализаций у данной функции нет. Во втором фрагменте кода специализация есть только у функции из строки 1, а у функции из строки 3 нет. В итоге вызывается функция из строки 3:
template <typename T> void foo(T*); // строка 3
По это причине не рекомендуется одновременно использовать перегрузки функций и их полную специализацию.

Куда сходить в Москве на выходных

Зеленым отметил, где уже был.
Желтым то, что хотелось бы посетить следующим.

суббота, 3 февраля 2018 г.

Способы вызвать крах программы в С++

Следующие способы вызвать крах программы в C++ взяты из книги Саттера.
  1. memset(0,1,1) - обращение по нулевому указателю
  2. abort()
  3. static_cast<char*>(0) = 0 - обращение по нулевому указателю
  4. static_cast<void(*)()>(0)() - вызов несуществующей функции по нулевому указателю
  5. throw std::logic_error()
  6. throw 0

воскресенье, 10 сентября 2017 г.

Загадка про охотника и ворону

На березе сидело четыре вороны. Пришел охотник и подстрелил одну. Сколько ворон осталось на березе?

четверг, 2 февраля 2017 г.

Книги для изучения C++

Начать изучение C++ рекомендуется с классической книги Б. Керниган, Д. Ритчи, "Язык программирования C". Понимание языка C, который лёг в основу C++, поможет вам лучше разобраться с особенностями C++. 

Дальше можно перейти к вводным курсам по С++.
  • Стенли Б. Липпман, Жози Лажойе, Барбара Э. Му "Язык программирования C++. Вводный курс".
  • Стивен Прата. "Язык программирования C++. Лекции и упражнения".
  • Герберт Шилдт. "Язык программирования C++. Вводный курс".
Кроме этого, для основательного понимания материала мы настоятельно советуем прочесть следующие книги по C++.
  • Скотт Майерс, "Эффективное использование С++".
  • Герб Саттер, Андрей Александреску, "Стандарты программирования на C++".
  • Герб Саттер, "Решение сложных задач на С++".
  • Герб Саттер, "Новые сложные задачи на C++".
Опытным слушателям могут показаться интересными следующие книги.
  • Андрея Александреску, "Современное проектирование на С++".
  • Бьерн Страуструп, "Дизайн и эволюция языка C++".

воскресенье, 28 февраля 2016 г.

Задача про визирей и жен

Было у султана N=12 визирей. Узнал он как-то, что у некоторых визирей неверные жены. Решил он им наказание устроить. Сделал так: каждого визиря с его женой посадили в полностью изолированные комнаты, и было им сказано, что сидеть им взаперти, пока все неверные жены не будут убиты своими супругами. Каждое утро все комнаты обходит слуга, проверяя выполнение этого условия. Как только выясняется, что все неверные жены мертвы, всех выпускают. На K=3-ий день всех выпустили, причем все верные жены остались живы. Как визири догадались? Уточнение. Все визири очень умны, и сплетней во дворце предостаточно, так что каждый визирь знает, верная или неверная жена у каждого другого визиря, но ничего не знает про свою. Никакого обмена информацией, пока они взаперти, нет.