
- Главная
- Каталог
- Образование
- C++ geek
Статистика канала
if, превращаясь в настоящий лабиринт. Давайте разберем, как этого избежать.
❌ Плохой пример: Вложенные условия
void process(int value) {
if (value > 0) {
if (value % 2 == 0) {
if (value < 100) {
std::cout << "Обрабатываем " << value << std::endl;
} else {
std::cout << "Слишком большое число" << std::endl;
}
} else {
std::cout << "Нечетное число" << std::endl;
}
} else {
std::cout << "Отрицательное число" << std::endl;
}
}
{}
Здесь код уходит вглубь из-за множества вложенных if, что делает его сложным для чтения.
✅ Хороший пример: Ранний возврат
void process(int value) {
if (value <= 0) {
std::cout << "Отрицательное число" << std::endl;
return;
}
if (value % 2 != 0) {
std::cout << "Нечетное число" << std::endl;
return;
}
if (value >= 100) {
std::cout << "Слишком большое число" << std::endl;
return;
}
std::cout << "Обрабатываем " << value << std::endl;
}
{}
Теперь код сразу проверяет граничные условия и делает ранний возврат (return), если условия не выполнены. В итоге у нас получился плоский код, который проще читать и сопровождать.
🎯 Вывод:
- Избегайте вложенных if, если можно этого не делать.
- Используйте ранний возврат, чтобы код был линейным и понятным.
- Чем меньше уровней вложенности — тем легче отладка и сопровождение.
➡️ @cpp_geekstd::vector. Детали внутреннего устройства std::vector в подробностях продолжают изучать в вузах, спрашивать на собеседованиях, обсуждать на конференциях. То же самое происходит с контейнерами std::list, std::deque, std::map и std::unordered_map: про их реализацию и особенности внутреннего устройства можно говорить бесконечно долго, про них все еще делают доклады, снимают лекции и пишут статьи. И их продолжают использовать в продакшен-коде даже в самых крупных и известных компаниях.
При этом в библиотеке Boost давным-давно есть альтернативные версии контейнеров, которые выигрывают у стандартных по многим показателям. Однако об этих версиях почти никто не знает, о них почти нет лекций, статей и докладов. Пора положить этому конец и разобраться в том, как еще могут быть устроены контейнеры, помимо тех версий из STL, о которых и так все знают.
Спикер обсудил внутреннее устройство не таких уж стандартных контейнеров: stable_vector, devector, bimap, circular_buffer, а также интрузивных версий list, map, unordered_map и их разновидностей.
источник
➡️ @cpp_geekstd::move правильно!
Привет, друзья! Сегодня я расскажу об одной из самых частых ошибок, связанных с std::move. Многие знают, что std::move не перемещает объект, а лишь превращает его в rvalue. Но как его использовать правильно? Давайте разбираться!
❌ Ошибка: Бессмысленный std::move
std::string getString() {
std::string str = "Hello, world!";
return std::move(str); // ❌ Неэффективно
}
{}
Что здесь не так? Возвращаемый std::string и так является временным объектом (NRVO — оптимизация возврата), и std::move мешает этой оптимизации! В результате компилятор не сможет выполнить перемещение, а вызовет копирование.
✅ Правильный вариант:
std::string getString() {
return "Hello, world!"; // ✅ NRVO оптимизация
}
{}
🏆 Где std::move полезен?
Используйте std::move, когда точно знаете, что объект больше не нужен и его можно переместить:
void processString(std::string str) { /* ... */ }
int main() {
std::string s = "Example";
processString(std::move(s)); // 🔥 Теперь перемещение!
}
{}
1️⃣ Не используйте std::move при возврате локальных объектов — дайте компилятору сделать свое дело!
2️⃣ Используйте std::move, когда объект больше не нужен — это ускорит работу кода.
3️⃣ После std::move не используйте переменную, кроме как для присвоения нового значения.
➡️ @cpp_geekif, превращаясь в настоящий лабиринт. Давайте разберем, как этого избежать.
❌ Плохой пример: Вложенные условия
void process(int value) {
if (value > 0) {
if (value % 2 == 0) {
if (value < 100) {
std::cout << "Обрабатываем " << value << std::endl;
} else {
std::cout << "Слишком большое число" << std::endl;
}
} else {
std::cout << "Нечетное число" << std::endl;
}
} else {
std::cout << "Отрицательное число" << std::endl;
}
}
{}
Здесь код уходит вглубь из-за множества вложенных if, что делает его сложным для чтения.
✅ Хороший пример: Ранний возврат
void process(int value) {
if (value <= 0) {
std::cout << "Отрицательное число" << std::endl;
return;
}
if (value % 2 != 0) {
std::cout << "Нечетное число" << std::endl;
return;
}
if (value >= 100) {
std::cout << "Слишком большое число" << std::endl;
return;
}
std::cout << "Обрабатываем " << value << std::endl;
}
{}
Теперь код сразу проверяет граничные условия и делает ранний возврат (return), если условия не выполнены. В итоге у нас получился плоский код, который проще читать и сопровождать.
🎯 Вывод:
- Избегайте вложенных if, если можно этого не делать.
- Используйте ранний возврат, чтобы код был линейным и понятным.
- Чем меньше уровней вложенности - тем легче отладка и сопровождение.
➡️ @cpp_geekif, превращаясь в настоящий лабиринт. Давайте разберем, как этого избежать.
❌ Плохой пример: Вложенные условия
void process(int value) {
if (value > 0) {
if (value % 2 == 0) {
if (value < 100) {
std::cout << "Обрабатываем " << value << std::endl;
} else {
std::cout << "Слишком большое число" << std::endl;
}
} else {
std::cout << "Нечетное число" << std::endl;
}
} else {
std::cout << "Отрицательное число" << std::endl;
}
}
{}
Здесь код уходит вглубь из-за множества вложенных if, что делает его сложным для чтения.
✅ Хороший пример: Ранний возврат
void process(int value) {
if (value <= 0) {
std::cout << "Отрицательное число" << std::endl;
return;
}
if (value % 2 != 0) {
std::cout << "Нечетное число" << std::endl;
return;
}
if (value >= 100) {
std::cout << "Слишком большое число" << std::endl;
return;
}
std::cout << "Обрабатываем " << value << std::endl;
}
{}
Теперь код сразу проверяет граничные условия и делает ранний возврат (return), если условия не выполнены. В итоге у нас получился плоский код, который проще читать и сопровождать.
🎯 Вывод:
- Избегайте вложенных if, если можно этого не делать.
- Используйте ранний возврат, чтобы код был линейным и понятным.
- Чем меньше уровней вложенности — тем легче отладка и сопровождение.
➡️ @cpp_geek
#include <iostream>
#include <string_view>
void print(std::string_view str) { // Без лишнего копирования
std::cout << str << '\n';
}
int main() {
std::string s = "Hello, world!";
print(s); // Можно передавать std::string
print("Hi there"); // Можно передавать строковый литерал
}
{}
🛠 Когда использовать?
✅ При передаче строк в функции, если их не нужно модифицировать.
✅ Для работы с подстроками (в отличие от std::string::substr, который делает копию).
✅ Для обработки строк без создания динамических объектов.
⚠️ Важно помнить:
- std::string_view не владеет данными, поэтому нельзя использовать его для длительного хранения указателей на временные строки.
- Нужно быть осторожным с объектами, чей срок жизни может закончиться, пока std::string_view ещё используется.
🚀 Итог:
Использование std::string_view вместо const std::string& может ускорить работу с текстовыми данными и снизить нагрузку на аллокатор. Если не нужно изменять строку — это отличный выбор!
А вы уже используете std::string_view в своих проектах? Делитесь в комментариях! ⬇️
➡️ @cpp_geek
g++ -o my_program my_program.cpp -O2 -s
{}
Флаг -s удаляет все отладочные символы.
🔹 2. Оптимизируем код
Используйте -O2 или -Os, чтобы компилятор оптимизировал код для уменьшения размера:
g++ -o my_program my_program.cpp -Os
{}
Флаг -Os специально оптимизирует код для минимального размера.
🔹 3. Статическая или динамическая линковка?
Если в системе уже есть нужные библиотеки, используйте динамическую линковку (-shared для .so в Linux, /MD в MSVC).
Но иногда статическая линковка (флаг -static) позволяет избавиться от лишних зависимостей.
🔹 4. Убираем ненужные зависимости
Можно использовать strip, чтобы дополнительно очистить бинарник:
strip my_program
{}
А ещё, если пишете на C++, то не забывайте про -ffunction-sections -fdata-sections и --gc-sections, чтобы убрать неиспользуемый код.
🔹 5. Убираем RTTI и исключения
Если не используете dynamic_cast и исключения, отключите их:
g++ -o my_program my_program.cpp -Os -fno-rtti -fno-exceptions
{}
Это существенно уменьшит размер!
➡️ @cpp_geekstd::unordered_map в C++
Сегодня я расскажу вам, как оптимизировать работу std::unordered_map и избежать неожиданных тормозов.
std::unordered_map — мощная хеш-таблица в C++, но при неправильном использовании она может замедлить ваш код. Давайте разберем основные моменты, которые помогут избежать проблем.
🔥 1. Выбирайте правильный хеш-функтор
По умолчанию std::unordered_map использует std::hash<Key>, но если ключ — это пользовательский тип данных (например, struct`), то стандартного `std::hash не существует, и придется писать свой.
Пример кастомного хеша для структуры:
struct MyKey {
int x, y;
bool operator==(const MyKey& other) const {
return x == other.x && y == other.y;
}
};
struct MyHash {
size_t operator()(const MyKey& key) const {
return std::hash<int>{}(key.x) ^ (std::hash<int>{}(key.y) << 1);
}
};
std::unordered_map<MyKey, std::string, MyHash> my_map;
{}
Используем ^ (XOR) и << (битовый сдвиг), чтобы уменьшить коллизии.
⚡ 2. Контролируйте размер bucket'ов
Если std::unordered_map сильно увеличивается, он перехеширует (rehash), что может быть дорогой операцией. Чтобы избежать лишних перераспределений:
my_map.reserve(10000); // Подготавливаем место под 10,000 элементов
{}
Это ускорит вставку, так как уменьшит количество перераспределений памяти.
🚀 3. Избегайте ненужного копирования ключей
Если ключ — это сложный объект, избегайте его копирования:
std::unordered_map<std::string, int> data;
std::string key = "long_key_string";
int value = data[key]; // ❌ НЕ ЭФФЕКТИВНО: создаст пустую запись, если ключа нет
int value = data.at(key); // ✅ БЫСТРЕЕ: выбросит исключение, если ключа нет
{}
Еще лучше использовать find():
auto it = data.find(key);
if (it != data.end()) {
int value = it->second;
}
{}
🏆 Вывод
✅ Используйте кастомные хеш-функции, если ключи нестандартные
✅ Резервируйте память заранее (reserve)
✅ Уменьшайте копирование ключей, используя find() и at()
А вы используете std::unordered_map в своих проектах? Может, у вас есть свои фишки? Пишите в комментариях! 👇🚀
➡️ @cpp_geekОтзывы канала
- Добавлен: Сначала новые
- Добавлен: Сначала старые
- Оценка: По убыванию
- Оценка: По возрастанию
Каталог Телеграм-каналов для нативных размещений
C++ geek — это Telegam канал в категории «Образование», который предлагает эффективные форматы для размещения рекламных постов в Телеграмме. Количество подписчиков канала в 3.7K и качественный контент помогают брендам привлекать внимание аудитории и увеличивать охват. Рейтинг канала составляет 6.6, количество отзывов – 1, со средней оценкой 5.0.
Вы можете запустить рекламную кампанию через сервис Telega.in, выбрав удобный формат размещения. Платформа обеспечивает прозрачные условия сотрудничества и предоставляет детальную аналитику. Стоимость размещения составляет 4195.8 ₽, а за 4 выполненных заявок канал зарекомендовал себя как надежный партнер для рекламы в TG. Размещайте интеграции уже сегодня и привлекайте новых клиентов вместе с Telega.in!
Вы снова сможете добавить каналы в корзину из каталога
Комментарий