Получите клиентов в любой нише!
Делегируйте запуск рекламы нам — бесплатно
Подробнее
24.3
Грокаем C++
5.0
5
Авторский канал о программировании на С++ и базе computer science. Простым и легким слогом рассказываем про сложные концепции С++. Самая активная и вовлеченная аудитория в тематике.
Поделиться
В избранное
Купить рекламу в этом канале
Формат:
keyboard_arrow_down
- 1/24
- 2/48
- 3/72
- Нативный
- 7 дней
- Репост
1 час в топе / 24 часа в ленте
Количество:
%keyboard_arrow_down
- 1
- 2
- 3
- 4
- 5
- 8
- 10
- 15
Стоимость публикации:
local_activity
8 391.60₽8 391.60₽local_mall
0.0%
Последние посты канала
imageИзображение не доступно для предпросмотра
Считаем единички
#задачки
Меня всегда забавляли задачки на бинарное представление чисел. Всегда можно найти занимательные и новые для себя подходы.
Вроде бы простая и популярная задача: посчитать количество единиц в битовом представлении числа. Уверен, что большинство из вас решали эту задачу.
Однако популярный подход - не самый эффективный, элегантный и интересный.
Благо существует множество непопулярных, но очень интересных решений! О них я расскажу в завтра в ответном посте.
А пока предлагаю вам порешать эту задачку. Если вы знаете какие-то нетривиальные решения, то расскажите о них в комментах тоже.
А чтобы умудренным опытом людям было немного интереснее, давайте ограничим условия. Задачу надо решить либо за константное время(в среднем), либо за наименьшее количество строчек. Выражения вне цикла for разделенные символом
Challenge yourself. Stay cool.
#задачки
Меня всегда забавляли задачки на бинарное представление чисел. Всегда можно найти занимательные и новые для себя подходы.
Вроде бы простая и популярная задача: посчитать количество единиц в битовом представлении числа. Уверен, что большинство из вас решали эту задачу.
Однако популярный подход - не самый эффективный, элегантный и интересный.
Благо существует множество непопулярных, но очень интересных решений! О них я расскажу в завтра в ответном посте.
А пока предлагаю вам порешать эту задачку. Если вы знаете какие-то нетривиальные решения, то расскажите о них в комментах тоже.
А чтобы умудренным опытом людям было немного интереснее, давайте ограничим условия. Задачу надо решить либо за константное время(в среднем), либо за наименьшее количество строчек. Выражения вне цикла for разделенные символом
;
считаются разными строчками.int count_ones(unsigned num) {
// Here your code
}
Challenge yourself. Stay cool.
1500
09:00
31.01.2025
imageИзображение не доступно для предпросмотра
Считаем единички
#задачки
Меня всегда забавляли задачки на бинарное представление чисел. Всегда можно найти занимательные и новые для себя подходы.
Вроде бы простая и популярная задача: посчитать количество единиц в битовом представлении числа. Уверен, что большинство из вас решали эту задачу.
Однако популярный подход - не самый эффективный, элегантный и интересный.
Благо существует множество непопулярных, но очень интересных решений! О них я расскажу в завтра в ответном посте.
А пока предлагаю вам порешать эту задачку. Если вы знаете какие-то нетривиальные решения, то расскажите о них в комментах тоже.
А чтобы умудренным опытом людям было немного интереснее, давайте ограничим условия. Задачу надо решить либо за константное время(в среднем), либо за наименьшее количество строчек. Выражения вне цикла for разделенные символом
Challenge yourself. Stay cool.
#задачки
Меня всегда забавляли задачки на бинарное представление чисел. Всегда можно найти занимательные и новые для себя подходы.
Вроде бы простая и популярная задача: посчитать количество единиц в битовом представлении числа. Уверен, что большинство из вас решали эту задачу.
Однако популярный подход - не самый эффективный, элегантный и интересный.
Благо существует множество непопулярных, но очень интересных решений! О них я расскажу в завтра в ответном посте.
А пока предлагаю вам порешать эту задачку. Если вы знаете какие-то нетривиальные решения, то расскажите о них в комментах тоже.
А чтобы умудренным опытом людям было немного интереснее, давайте ограничим условия. Задачу надо решить либо за константное время(в среднем), либо за наименьшее количество строчек. Выражения вне цикла for разделенные символом
;
считаются разными строчками.int count_ones(unsigned num) {
// Here your code
}
Challenge yourself. Stay cool.
1500
09:00
31.01.2025
Перфорируем код
С++ - язык для высокопроизводительных вычислений. В проектах, где критически важна скорость вычислений, приходится пользоваться различного рода тулзами для проверки производительности кода. Выискивать застои, боттлнеки, говнооптимизации и овернагруженные функции. Не так много хороших и удобных решений есть на рынке. Но похоже, что ситуация изменяется.
Кто бы что ни говорил, а Яндекс делает крутые продукты для разработчиков. Это огромная компания с большой экспертизой. И если чего-то хорошего нет на рынке, то они это делают сами. И нередко Яндекс выкладывают свои наработки в опенсорс. Чего стоит только userver, без которого писать микросервисы, мягко говоря, неудобно.
Также у них у самих дофига сервисов, которые крутятся на их серверах. Поэтому помимо того, что надо сами сервисы профилировать, так надо как-то понимать, адекватно ли они вообще тратят ресурсы своих железок. Поэтому идея сделать свой профилировщик сама пришла со временем.
B вот недавно они выкатили на гитхаб свой инструмент Perforator, который используют для анализа производительности большинства своих сервисов. Причем тулза настолько крутая, что на ее работу уходит примерно 0.2% CPU и 1% RAM. Поэтому они буквально каждый свой сервис профилируют этим перфоратором прям в проде.
Как он работает? Это вопрос сложный и требует начального понимания, что как работает утилита perf. Но, в целом, если интересно подробно разобраться, то у них есть видеодоклад про Perforator и на основе чего он построен.
Тулза поддерживает поддерживает нативные языки (C++, C, Go, Rust), а также экспериментально Python и Java. Ещё его можно развёртывать на Kubernetes и локально. В общем, раздолье для экспериментов.
🌐 Уже сейчас Perforator можно скачать и протестировать самому, подробности — в статье на Хабре. Исходный код доступен под лицензией MIT (и GPL — для eBPF-программ) и запускается под x86-64 Linux. Визуализацию работы сервиса можно глянуть тут.
Кажется, что это крутой инструмент и хотя бы потыкаться в него точно стоит.
Measure your performance. Stay cool.
Реклама. ООО "Яндекс", ИНН 7736207543.
С++ - язык для высокопроизводительных вычислений. В проектах, где критически важна скорость вычислений, приходится пользоваться различного рода тулзами для проверки производительности кода. Выискивать застои, боттлнеки, говнооптимизации и овернагруженные функции. Не так много хороших и удобных решений есть на рынке. Но похоже, что ситуация изменяется.
Кто бы что ни говорил, а Яндекс делает крутые продукты для разработчиков. Это огромная компания с большой экспертизой. И если чего-то хорошего нет на рынке, то они это делают сами. И нередко Яндекс выкладывают свои наработки в опенсорс. Чего стоит только userver, без которого писать микросервисы, мягко говоря, неудобно.
Также у них у самих дофига сервисов, которые крутятся на их серверах. Поэтому помимо того, что надо сами сервисы профилировать, так надо как-то понимать, адекватно ли они вообще тратят ресурсы своих железок. Поэтому идея сделать свой профилировщик сама пришла со временем.
B вот недавно они выкатили на гитхаб свой инструмент Perforator, который используют для анализа производительности большинства своих сервисов. Причем тулза настолько крутая, что на ее работу уходит примерно 0.2% CPU и 1% RAM. Поэтому они буквально каждый свой сервис профилируют этим перфоратором прям в проде.
Как он работает? Это вопрос сложный и требует начального понимания, что как работает утилита perf. Но, в целом, если интересно подробно разобраться, то у них есть видеодоклад про Perforator и на основе чего он построен.
Тулза поддерживает поддерживает нативные языки (C++, C, Go, Rust), а также экспериментально Python и Java. Ещё его можно развёртывать на Kubernetes и локально. В общем, раздолье для экспериментов.
🌐 Уже сейчас Perforator можно скачать и протестировать самому, подробности — в статье на Хабре. Исходный код доступен под лицензией MIT (и GPL — для eBPF-программ) и запускается под x86-64 Linux. Визуализацию работы сервиса можно глянуть тут.
Кажется, что это крутой инструмент и хотя бы потыкаться в него точно стоит.
Measure your performance. Stay cool.
Реклама. ООО "Яндекс", ИНН 7736207543.
1900
16:00
30.01.2025
Итоги конкурса
Мы долго ждали и, наконец, дождались. Вчера я честно взял генератор случайных чисел и нашел победителя и будущего счастливого обладателя книжки "С++. Практика многопоточного программирования" Энтони Уильямса. Ботов розыгрышей не хотелось использовать, без души все это. Надеюсь, вы доверяете моей непредвзятости)
Но перед оглашение результатов хочу поблагодарить всех участников этого экспериментального формата. Спасибо вам, что поддержали инициативу! Так много новых лиц увидел в комментах. Будем надеяться, что все больше людей будет присоединяться к коммьюнити и делиться свои профессиональным опытом.
Ну а победителем стал Илья Морозов давайте похлопаем ему👏👏👏. Илья, пиши в лс по ссылке в профиле канала, чтобы получить свою книжку.
Будем работать, чтобы таких розыгрышей было больше. Поэтому мягко напоминаю, что у Питера самый качественный перевод зарубежных книг. А там сами все найдете.
Be lucky. Stay cool.
Мы долго ждали и, наконец, дождались. Вчера я честно взял генератор случайных чисел и нашел победителя и будущего счастливого обладателя книжки "С++. Практика многопоточного программирования" Энтони Уильямса. Ботов розыгрышей не хотелось использовать, без души все это. Надеюсь, вы доверяете моей непредвзятости)
Но перед оглашение результатов хочу поблагодарить всех участников этого экспериментального формата. Спасибо вам, что поддержали инициативу! Так много новых лиц увидел в комментах. Будем надеяться, что все больше людей будет присоединяться к коммьюнити и делиться свои профессиональным опытом.
Ну а победителем стал Илья Морозов давайте похлопаем ему👏👏👏. Илья, пиши в лс по ссылке в профиле канала, чтобы получить свою книжку.
Будем работать, чтобы таких розыгрышей было больше. Поэтому мягко напоминаю, что у Питера самый качественный перевод зарубежных книг. А там сами все найдете.
Be lucky. Stay cool.
2500
09:00
28.01.2025
Наследование? От лямбды? Ч3
А давайте сделаем еще один шаг вперед. Зачем нам наследоваться от какого-то фиксированного количества лямбд? Не будем себя ничем ограничивать. Давайте наследоваться от произвольного количества!
И что нам этот шаг дал?
Теперь мы можем благодаря variadic templates в компайл-тайме генерить структурки, которые включают произвольное количество различных вариантов вызвов оператора(). И слово "вариант" здесь неспроста.
Помните наш std::visit? Который применяет визитор к объекту варианта.
Так вот теперь мы можем налету делать наши визиторы!
Создаем вектор, который может содержать 3 типа. И не так уж просто обрабатывать элементы такого вектора. Но вооружившись std::visit и созданным налету нашим Visitor'ом мы играючи обошли все элементы и красиво вывели их на экран:
Визитор - довольно интересный паттерн. И круто, что мы с вами смогли до него дойти из, казалось бы, такой неочевидной темы, как наследование от лямбд.
Но вообще, конкретно вот эта конструкция с наследованием от лямбд называется overload паттерн. Это стандартное и более короткое название для этого дизайн решения.
@monah_tuk как-то в комментах напомнил о прекрасной тулзе, где вы можете посмотреть чуть более легкосмотрибельную версию вашего кода. Жмякнув сюда вы сможете посмотреть, во что превращается код из этого поста и, возможно, понять чуть больше.
Visit your close ones. Stay cool.
#template #design #cpp17
А давайте сделаем еще один шаг вперед. Зачем нам наследоваться от какого-то фиксированного количества лямбд? Не будем себя ничем ограничивать. Давайте наследоваться от произвольного количества!
template<typename ... Lambdas>
struct DerivedFromLambdas : Lambdas...
{
DerivedFromLambdas(Lambdas... lambdas) : Lambdas(std::forward<Lambdas>(lambdas))... {}
using Lambdas::operator()...;
};
И что нам этот шаг дал?
Теперь мы можем благодаря variadic templates в компайл-тайме генерить структурки, которые включают произвольное количество различных вариантов вызвов оператора(). И слово "вариант" здесь неспроста.
Помните наш std::visit? Который применяет визитор к объекту варианта.
Так вот теперь мы можем налету делать наши визиторы!
template<typename ... Lambdas>
struct Visitor : Lambdas...
{
Visitor(Lambdas... lambdas) : Lambdas(std::forward<Lambdas>(lambdas))...
{
}
using Lambdas::operator()...;
};
using var_t = std::variant<int, double, std::string>;
int main(){
std::vector<var_t> vec = {10, 1.5, "hello"};
std::for_each(vec.begin(),
vec.end(),
[](const auto& v)
{
std::visit(Visitor{
[](int arg) { std::cout << arg << ' '; },
[](double arg) { std::cout << std::fixed << arg << ' '; },
[](const std::string& arg) { std::cout << std::quoted(arg) << ' '; } }
, v);
});
}
Создаем вектор, который может содержать 3 типа. И не так уж просто обрабатывать элементы такого вектора. Но вооружившись std::visit и созданным налету нашим Visitor'ом мы играючи обошли все элементы и красиво вывели их на экран:
10 1.500000 "hello"
Визитор - довольно интересный паттерн. И круто, что мы с вами смогли до него дойти из, казалось бы, такой неочевидной темы, как наследование от лямбд.
Но вообще, конкретно вот эта конструкция с наследованием от лямбд называется overload паттерн. Это стандартное и более короткое название для этого дизайн решения.
@monah_tuk как-то в комментах напомнил о прекрасной тулзе, где вы можете посмотреть чуть более легкосмотрибельную версию вашего кода. Жмякнув сюда вы сможете посмотреть, во что превращается код из этого поста и, возможно, понять чуть больше.
Visit your close ones. Stay cool.
#template #design #cpp17
3200
09:00
26.01.2025
Наследование? От лямбды? Ч2
#опытным
Лямбды - это функциональные объекты по своей сути. Объекты классов с перегруженным оператором(). Зачем вообще от такой сущности наследоваться? Можно же просто сделать обычный класс с такими же перегруженным оператором и расширять его сколько влезет.
Ну как будто бы да. От одной лямбды наследоваться особо нет смысла. А что насчет множественного наследования?
Идейно - наш наследник будет наследовать публичный интерфейс всех своих родителей. То есть в наследнике будет много перегруженных операторов() для разных входных параметров. Вот это уже чуть удобнее. Мы можем находу создавать объект, который единообразно с помощью перегрузок будет обрабатывать какие-то вещи.
Покажу чуть подробнее:
Логика и механика те же, что и в прошлом посте. Только теперь мы налету конструируем объект, который умеет в 2 перегрузки функции. Если эти перегрузки действительно небольшие, то не особо понятно, зачем мне определять их как отдельные перегрузки отдельной функции. Это нужно будет их потом по коду искать. А тут все рядышком и смотреть приятно.
Только не наследуйтесь от нескольких лямбд, которые принимают одинаковый набор параметров. Компилятор не сможет разрезолвить, от какого конкретно родителя вы хотите вызвать перегрузку и билд упадет.
Дальние ряды уже начали догадываться зачем такая конструкция реально может быть нужна. Но все объяснения в следующий раз.
Have a sense. Stay cool.
#template #cppcore #cpp17
#опытным
Лямбды - это функциональные объекты по своей сути. Объекты классов с перегруженным оператором(). Зачем вообще от такой сущности наследоваться? Можно же просто сделать обычный класс с такими же перегруженным оператором и расширять его сколько влезет.
Ну как будто бы да. От одной лямбды наследоваться особо нет смысла. А что насчет множественного наследования?
Идейно - наш наследник будет наследовать публичный интерфейс всех своих родителей. То есть в наследнике будет много перегруженных операторов() для разных входных параметров. Вот это уже чуть удобнее. Мы можем находу создавать объект, который единообразно с помощью перегрузок будет обрабатывать какие-то вещи.
Покажу чуть подробнее:
template<class Lambda1, class Lambda2>
struct DerivedFromLambdas : public Lambda1, Lambda2
{
DerivedFromLambdas(Lambda1 lambda1, Lambda2 lambda2)
: Lambda1(std::move(lambda1))
, Lambda2{std::move(lambda2)} {}
using Lambda1::operator();
using Lambda2::operator();
};
int main(){
DerivedFromLambdas child{[](int i){return "takes int";}, [](double d){return "takes double";}};
std::cout << child(42) << std::endl;
std::cout << child(42.0) << std::endl;
return 0;
}
// OUTPUT:
// takes int
// takes double
Логика и механика те же, что и в прошлом посте. Только теперь мы налету конструируем объект, который умеет в 2 перегрузки функции. Если эти перегрузки действительно небольшие, то не особо понятно, зачем мне определять их как отдельные перегрузки отдельной функции. Это нужно будет их потом по коду искать. А тут все рядышком и смотреть приятно.
Только не наследуйтесь от нескольких лямбд, которые принимают одинаковый набор параметров. Компилятор не сможет разрезолвить, от какого конкретно родителя вы хотите вызвать перегрузку и билд упадет.
Дальние ряды уже начали догадываться зачем такая конструкция реально может быть нужна. Но все объяснения в следующий раз.
Have a sense. Stay cool.
#template #cppcore #cpp17
3100
09:00
24.01.2025
Наследование? От лямбды? Ч2
#опытным
Лямбды - это функциональные объекты по своей сути. Объекты классов с перегруженным оператором(). Зачем вообще от такой сущности наследоваться? Можно же просто сделать обычный класс с такими же перегруженным оператором и расширять его сколько влезет.
Ну как будто бы да. От одной лямбды наследоваться особо нет смысла. А что насчет множественного наследования?
Идейно - наш наследник будет наследовать публичный интерфейс всех своих родителей. То есть в наследнике будет много перегруженных операторов() для разных входных параметров. Вот это уже чуть удобнее. Мы можем находу создавать объект, который единообразно с помощью перегрузок будет обрабатывать какие-то вещи.
Покажу чуть подробнее:
Логика и механика те же, что и в прошлом посте. Только теперь мы налету конструируем объект, который умеет в 2 перегрузки функции. Если эти перегрузки действительно небольшие, то не особо понятно, зачем мне определять их как отдельные перегрузки отдельной функции. Это нужно будет их потом по коду искать. А тут все рядышком и смотреть приятно.
Только не наследуйтесь от нескольких лямбд, которые принимают одинаковый набор параметров. Компилятор не сможет разрезолвить, от какого конкретно родителя вы хотите вызвать перегрузку и билд упадет.
Дальние ряды уже начали догадываться зачем такая конструкция реально может быть нужна. Но все объяснения в следующий раз.
Have a sense. Stay cool.
#template #cppcore #cpp17
#опытным
Лямбды - это функциональные объекты по своей сути. Объекты классов с перегруженным оператором(). Зачем вообще от такой сущности наследоваться? Можно же просто сделать обычный класс с такими же перегруженным оператором и расширять его сколько влезет.
Ну как будто бы да. От одной лямбды наследоваться особо нет смысла. А что насчет множественного наследования?
Идейно - наш наследник будет наследовать публичный интерфейс всех своих родителей. То есть в наследнике будет много перегруженных операторов() для разных входных параметров. Вот это уже чуть удобнее. Мы можем находу создавать объект, который единообразно с помощью перегрузок будет обрабатывать какие-то вещи.
Покажу чуть подробнее:
template<class Lambda1, class Lambda2>
struct DerivedFromLambdas : public Lambda1, Lambda2
{
DerivedFromLambdas(Lambda1 lambda1, Lambda2 lambda2)
: Lambda1(std::move(lambda1))
, Lambda2{std::move(lambda2)} {}
using Lambda1::operator();
using Lambda2::operator();
};
int main(){
DerivedFromLambdas child{[](int i){return "takes int";}, [](double d){return "takes double";}};
std::cout << child(42) << std::endl;
std::cout << child(42.0) << std::endl;
return 0;
}
// OUTPUT:
// takes int
// takes double
Логика и механика те же, что и в прошлом посте. Только теперь мы налету конструируем объект, который умеет в 2 перегрузки функции. Если эти перегрузки действительно небольшие, то не особо понятно, зачем мне определять их как отдельные перегрузки отдельной функции. Это нужно будет их потом по коду искать. А тут все рядышком и смотреть приятно.
Только не наследуйтесь от нескольких лямбд, которые принимают одинаковый набор параметров. Компилятор не сможет разрезолвить, от какого конкретно родителя вы хотите вызвать перегрузку и билд упадет.
Дальние ряды уже начали догадываться зачем такая конструкция реально может быть нужна. Но все объяснения в следующий раз.
Have a sense. Stay cool.
#template #cppcore #cpp17
3100
09:00
24.01.2025
Наследование? От лямбды? Ч1
#опытным
Наследованием в языке С++ никого не удивить. Все постоянно его видят в коде и используют. Но что, если я вам скажу, что вы можете наследоваться от лямбды! Как? Давайте разбираться.
Как это вообще возможно?
Ну это не удивительно для тех, кто знает, чем на самом деле являются лямбды. Это по сути своей классы, чей тип знает только сам компилятор, с перегруженным оператором(). То, что ее называют безымянной функцией, это не совсем правда. Все у нее есть.
То есть это класс, у которого есть вполне конкретный метод и даже поля(тут зависит от того, что захватила лямбда).
Значит это вполне легальный кандидат на наследование!
Придется конечно немного поколдовать вокруг отсутствия имени, но для С++ это не проблема.
Ничего особенного. Мы просто создали класс-обертку над каким-то функциональным объектом и используем его оператор(), как свой.
Дальше создаем лямбду и создаем объект обертки, просто передавая лямбду в конструктор. Мы специально не указываем явно шаблонный параметр DerivedFromLambda, потому что мы не знаем настоящего имени лямбды. Мы даем возможность компилятору самому вывести нужный шаблонный тип на основании инициализатора. Это возможно благодаря фиче С++17 Class Template Argument Deduction.
Но даже и на С++11-14 можно написать подобное. Ведь у нас есть оператор decltype, который возвращает в точности тип того выражения, которое мы в него передали. Тогда мы бы создавали объект так:
Зачем это нужно только? К этому мы будем потихоньку подбираться следующие пару постов.
Do surprising things. Stay cool.
#template #cppcore #cpp11 #cpp17
#опытным
Наследованием в языке С++ никого не удивить. Все постоянно его видят в коде и используют. Но что, если я вам скажу, что вы можете наследоваться от лямбды! Как? Давайте разбираться.
Как это вообще возможно?
Ну это не удивительно для тех, кто знает, чем на самом деле являются лямбды. Это по сути своей классы, чей тип знает только сам компилятор, с перегруженным оператором(). То, что ее называют безымянной функцией, это не совсем правда. Все у нее есть.
То есть это класс, у которого есть вполне конкретный метод и даже поля(тут зависит от того, что захватила лямбда).
Значит это вполне легальный кандидат на наследование!
Придется конечно немного поколдовать вокруг отсутствия имени, но для С++ это не проблема.
template<class Lambda>
struct DerivedFromLambda : public Lambda
{
DerivedFromLambda(Lambda lambda) : Lambda(std::move(lambda)) {}
using Lambda::operator();
};
int main(){
auto lambda = []{return 42;};
DerivedFromLambda child{lambda};
std::cout << child() << std::endl;
}
// OUTPUT:
// 42
Ничего особенного. Мы просто создали класс-обертку над каким-то функциональным объектом и используем его оператор(), как свой.
Дальше создаем лямбду и создаем объект обертки, просто передавая лямбду в конструктор. Мы специально не указываем явно шаблонный параметр DerivedFromLambda, потому что мы не знаем настоящего имени лямбды. Мы даем возможность компилятору самому вывести нужный шаблонный тип на основании инициализатора. Это возможно благодаря фиче С++17 Class Template Argument Deduction.
Но даже и на С++11-14 можно написать подобное. Ведь у нас есть оператор decltype, который возвращает в точности тип того выражения, которое мы в него передали. Тогда мы бы создавали объект так:
auto lambda = []{return 42;};
DerivedFromLambda<decltype(lambda)> child{lambda};
Зачем это нужно только? К этому мы будем потихоньку подбираться следующие пару постов.
Do surprising things. Stay cool.
#template #cppcore #cpp11 #cpp17
3100
09:00
23.01.2025
Наследование? От лямбды? Ч1
#опытным
Наследованием в языке С++ никого не удивить. Все постоянно его видят в коде и используют. Но что, если я вам скажу, что вы можете наследоваться от лямбды! Как? Давайте разбираться.
Как это вообще возможно?
Ну это не удивительно для тех, кто знает, чем на самом деле являются лямбды. Это по сути своей классы, чей тип знает только сам компилятор, с перегруженным оператором(). То, что ее называют безымянной функцией, это не совсем правда. Все у нее есть.
То есть это класс, у которого есть вполне конкретный метод и даже поля(тут зависит от того, что захватила лямбда).
Значит это вполне легальный кандидат на наследование!
Придется конечно немного поколдовать вокруг отсутствия имени, но для С++ это не проблема.
Ничего особенного. Мы просто создали класс-обертку над каким-то функциональным объектом и используем его оператор(), как свой.
Дальше создаем лямбду и создаем объект обертки, просто передавая лямбду в конструктор. Мы специально не указываем явно шаблонный параметр DerivedFromLambda, потому что мы не знаем настоящего имени лямбды. Мы даем возможность компилятору самому вывести нужный шаблонный тип на основании инициализатора. Это возможно благодаря фиче С++17 Class Template Argument Deduction.
Но даже и на С++11-14 можно написать подобное. Ведь у нас есть оператор decltype, который возвращает в точности тип того выражения, которое мы в него передали. Тогда мы бы создавали объект так:
Зачем это нужно только? К этому мы будем потихоньку подбираться следующие пару постов.
Do surprising things. Stay cool.
#template #cppcore #cpp11 #cpp17
#опытным
Наследованием в языке С++ никого не удивить. Все постоянно его видят в коде и используют. Но что, если я вам скажу, что вы можете наследоваться от лямбды! Как? Давайте разбираться.
Как это вообще возможно?
Ну это не удивительно для тех, кто знает, чем на самом деле являются лямбды. Это по сути своей классы, чей тип знает только сам компилятор, с перегруженным оператором(). То, что ее называют безымянной функцией, это не совсем правда. Все у нее есть.
То есть это класс, у которого есть вполне конкретный метод и даже поля(тут зависит от того, что захватила лямбда).
Значит это вполне легальный кандидат на наследование!
Придется конечно немного поколдовать вокруг отсутствия имени, но для С++ это не проблема.
template<class Lambda>
struct DerivedFromLambda : public Lambda
{
DerivedFromLambda(Lambda lambda) : Lambda(std::move(lambda)) {}
using Lambda::operator();
};
int main(){
auto lambda = []{return 42;};
DerivedFromLambda child{lambda};
std::cout << child() << std::endl;
}
// OUTPUT:
// 42
Ничего особенного. Мы просто создали класс-обертку над каким-то функциональным объектом и используем его оператор(), как свой.
Дальше создаем лямбду и создаем объект обертки, просто передавая лямбду в конструктор. Мы специально не указываем явно шаблонный параметр DerivedFromLambda, потому что мы не знаем настоящего имени лямбды. Мы даем возможность компилятору самому вывести нужный шаблонный тип на основании инициализатора. Это возможно благодаря фиче С++17 Class Template Argument Deduction.
Но даже и на С++11-14 можно написать подобное. Ведь у нас есть оператор decltype, который возвращает в точности тип того выражения, которое мы в него передали. Тогда мы бы создавали объект так:
auto lambda = []{return 42;};
DerivedFromLambda<decltype(lambda)> child{lambda};
Зачем это нужно только? К этому мы будем потихоньку подбираться следующие пару постов.
Do surprising things. Stay cool.
#template #cppcore #cpp11 #cpp17
3100
09:00
23.01.2025
imageИзображение не доступно для предпросмотра
👩💻 Ваш код на C++ мог бы быть быстрее. Намного быстрее.
Почему ваши приложения работают медленнее, чем хотелось бы? Программа не использует потенциал процессора, а кэш и память работают в авральном режиме?
🗓 На открытом уроке «Оптимизация производительности на C++» 30 января в 20:00 мск мы разберем инструменты gprof, valgrind, Google Benchmark, секреты работы с кэш-памятью, управление памятью и даже оптимизации компилятора.
🦾 Присоединяйтесь к вебинару и сделайте свои приложения молниеносными!
Участники урока получат скидку на большое обучение на курс «C++ Developer. Professional».
➡️ Узнать больше и зарегистрироваться: https://otus.pw/jyMs/
#реклама
О рекламодателе
Почему ваши приложения работают медленнее, чем хотелось бы? Программа не использует потенциал процессора, а кэш и память работают в авральном режиме?
🗓 На открытом уроке «Оптимизация производительности на C++» 30 января в 20:00 мск мы разберем инструменты gprof, valgrind, Google Benchmark, секреты работы с кэш-памятью, управление памятью и даже оптимизации компилятора.
🦾 Присоединяйтесь к вебинару и сделайте свои приложения молниеносными!
Участники урока получат скидку на большое обучение на курс «C++ Developer. Professional».
➡️ Узнать больше и зарегистрироваться: https://otus.pw/jyMs/
#реклама
О рекламодателе
1800
08:00
23.01.2025
close
С этим каналом часто покупают
Отзывы канала
keyboard_arrow_down
- Добавлен: Сначала новые
- Добавлен: Сначала старые
- Оценка: По убыванию
- Оценка: По возрастанию
5.0
1 отзыва за 6 мес.
Превосходно (100%) За последние 6 мес
m
**cromarketing@****.ru
24.01.202513:24
5
Высокая конверсия
Показать еще
Новинки в тематике
Лучшие в тематике
Выбрано
0
каналов на сумму:0.00₽
Подписчики:
0
Просмотры:
Перейти в корзинуКупить за:0.00₽
Комментарий