Программирование на Си-плюс-плюс нельзя назвать привычным для современных разработчиков, но трюки, собранные в этой статье, значительно облегчат вам жизнь.
Препроцессор
Макрос на определение размера массива:
template char (&ArraySizeHelper(T (&array)[N]))[N]; #define arraysize(array) (sizeof(ArraySizeHelper(array)))
Это лучше, чем обычный sizeof(array)/sizeof(array[0]), потому что вызывает краш при компиляции, если переданный массив является просто указателем или нулевым указателем, тогда как более простые макросы беззвучно возвращают бесполезное значение. Подробный пример см. в статье PVS-Studio vs Chromium.
Предопределенные макросы:
#define expect(expr) if(!expr) cerr << "Assertion " << #expr \ " failed at " << __FILE__ << ":" << __LINE__ << endl; #define stringify(x) #x #define tostring(x) stringify(x) #define MAGIC_CONSTANT 314159 cout << "Value of MAGIC_CONSTANT=" << tostring(MAGIC_CONSTANT);
Макрос tostring – это общий трюк, конвертирующий значение переменной в строку. Ядро Linux использует множество подобных макросов.
Использование итераторов для быстрого сброса содержимого контейнера:
#define dbg(v) copy(v.begin(), v.end(), ostream_iterator<typeof(*v.begin())>(cout, " "))
Шаблон Voodoo
Вы можете настраивать шаблоны класса под конкретные значения или типы аргументов: так работает специализация шаблонов классов C++. Если это рекурсия, можно записывать базовые случаи, а затем определить общий шаблон как рекурсивную комбинацию этих случаев.
Например:
template struct Choose { enum {value = (n * Choose<n-1, r-1>::value) / r}; }; template struct Choose<n, 0> { enum {value = 1}; }; int main() { cout << Choose<8, 3>::value; int x[Choose<25, 3>::value]; }
Больше интересного по ссылке.
Менеджмент памяти и RAII
Вы можете создавать шаблоны, автоматически освобождающие ресурсы, когда они бездействуют, или когда счетчик ссылок доходит до 0. Решается это путем перезагрузки operator * и operator =. Вы можете передать право собственности, используя operator =, или обновить счетчик ссылок.
Программирование на Си-плюс-плюс и URI в коде
Вы можете поместить URI в свой код на C++, и компилятор не выдаст ошибку.
#include int main() { using namespace std; http://www.google.com int x = 5; cout << x; }
Любой идентификатор, за которым следует двоеточие, становится меткой goto в Си-плюс-плюс. Все, что следует за двойным слешем, воспринимается как комментарий. Именно поэтому в приведенном выше коде http – это метка, а //google.com/ – комментарий. Но компилятор может выдать предупреждение, так как заданная метка не используется.
Упрощаем дебаг
Определите оператор << для структур STL, чтобы упростить добавление отладочных выходов в ваш код. Это лучше, чем стандартные функции вывода. Также определите соответствующий макрос. Пример для C++:
#include #include #include
Ключевое слово auto
Программирование на Си-плюс-плюс предполагает использование auto для итерации по карте, вектору, множеству, etc. Это ключевое слово указывает, что тип объявляемой переменной будет автоматически определен на основе типа инициализируемого выражения.
Стандартный вариант:
vector vs; vs.push_back(4),vs.push_back(7),vs.push_back(9),vs.push_back(10); for (vector::iterator it = vs.begin(); it != vs.end(); ++it) cout << *it << ' ';cout<<'\n';
Используем:
vector vs; vs.push_back(4),vs.push_back(7),vs.push_back(9),vs.push_back(10); for (auto it: vs) cout << it << ' ';cout<<endl; vector vs; vs.push_back(4),vs.push_back(7),vs.push_back(9),vs.push_back(10); for (auto& it: vs) it*=3; for (auto it: vs) cout << it << ' ';cout<<endl;
Объявление переменной:
template auto mult(A x, B y) -> decltype(x * y){ return x * y; } int main(){ auto a = 3 * 2; //the return type is the type of operator (x*y) cout<<a<<endl; return 0; }
Парные трюки
pair<int, int> p; //Это p = make_pair(1, 2); //тождественно этому p = {1, 2}; //Так что pair<int, pair<char, long long> > p; //теперь проще p = {1, {'a', 2ll}};
Супер подключение
Просто используйте:
#include <bits/stdc++.h>
Эта библиотека включает в себя множество библиотек, которые нам нужны. Например, algorithm, iostream, vector и многие другие. Теперь вам не придется мучиться с запоминанием большого количества обязательных подключений.
Выводы
Можно долго распинаться на тему ненависти к C++, вытесняемому современными и актуальными языками, но поддержку существующих приложений никто не отменял. Приведенные в статье советы заметно ускорят процесс разработки и сохранят массу нервных клеток.
Дополнительная литература
- Все о трюке Бартона Накмана
- Современный дизайн C++: общие шаблоны программирования и дизайна
- The C++ Resources Network
- Умные указатели на C++ – GeeksforGeeks
- Подробнее о ключевом слове auto (C++)
- Больше трюков на языке C++
Также рекомендуем Вам посмотреть:
Что такое мультиметоды в C++?
Подборка книг по C++ для любого уровня
Комментарии