Современные возможности C++
C++ — это не просто C с классами, это очень мощный язык со многими функциями, предоставляемыми такими языками, как Python и JavaScript.
В этой статье я показал несколько функций, которые вы, возможно, знаете из Python или JavaScript, но которые вы можете использовать и в C++!!
Эта статья предназначена для людей с базовыми знаниями C++.
Оглавление
- Шаблоны
- Авто
- Функция переменного аргумента
- Стандартная библиотека шаблонов
- Цикл на основе диапазона
- Лямбда-выражения
Шаблоны
Предположим, вы хотите написать функцию с одинаковыми операциями для разных типов данных.
В Python это просто, поскольку одна и та же переменная может указывать на разные объекты разных типов. Таким образом, вы можете повторно использовать один и тот же код для всех типов.
Теперь в C++ одним из решений является перегрузка функции различными типами, но это потребует от вас написания большого количества кода, который в основном делает то же самое. Здесь идет использование шаблонов.
Вместо того, чтобы самостоятельно писать функции с различными типами, вы можете попросить компилятор сгенерировать их для вас с помощью шаблонов. Компилятор знает, какие функции генерировать на основе предоставленного параметра.
Давайте посмотрим на пример:
- Шаблонная функция для получения максимум двух значений, значение может быть любого типа данных.
#include <iostream> template <typename type> // Creating a template type max(type first, type second) { return first > second ? first : second; } int main() { std::cout << max<int>(2, 3) << "\n"; // 3 std::cout << max(3.4f, 4.2f) << "\n"; // 4.2 std::cout << max('C', 'S') << "\n"; // S return 0; }
- Первый вызов скажет компилятору создать функцию с заменой
type
наint
. - Точно так же второй и третий вызовы создадут функцию с заменой
type
наfloat
иchar
. - В первом вызове мы явно указали компилятору, что это тип
int
с нотацией<type>
.
Аналогичным образом вы можете создавать шаблоны для классов.
Чтобы узнать больше о шаблонах в C++, ознакомьтесь с этой статьей.
Авто
Вы можете вывести тип переменной во время компиляции, используя ключевое слово auto
.
Это полезно, когда переменная имеет сложный тип.
Вот пример auto
#include <iostream> #include <string>
int main() { auto an_int = 50; auto a_float = 10.5f; auto a_double = 100.12; auto a_char = 'S'; auto a_string = "String";
std::cout << an_int << "\n"; // 50 std::cout << a_float << "\n"; // 10.5 std::cout << a_double << "\n"; // 100.12 std::cout << a_char << "\n"; // S std::cout << a_string << "\n"; // String
return 0; }
Чтобы узнать больше об auto в C++, прочитайте эту статью
Функции переменных аргументов
Если вы знаете Python, то наверняка использовали *
для создания функции с переменным числом аргументов.
Вы можете сделать то же самое в C++, используя многоточие и вариативные шаблоны.
Давайте разберемся с этим на примере -
#include <iostream>
template <typename type> int sum(type n) { return n; }
template <typename first, typename... types> // Packing Arguments int sum(first n, types ...args) // Expanding Arguments { return n + sum(args...); }
int main() { int sum3 = sum(1,2,3); std::cout << sum3 << "\n"; // 6 int sum5 = sum(1,2,3,4,5); std::cout << sum5 << "\n"; // 15
return 0; }
Здесь ...
после typename
упаковывает все аргументы, переданные при вызове, в types
, а затем мы снова их распаковываем с ...
перед args
.
Затем мы использовали рекурсию для вызова функции с аргументами на единицу меньше исходного.
Точно так же вы можете создать функцию печати, которая принимает любое количество аргументов.
#include <iostream>
template <typename First> void print(First first) { std::cout << first << "\n"; }
template <typename First, typename ... Types> void print(First first, Types ... args) { std::cout << first << " "; print(args...); }
int main() { print("One", "Two"); print("One", "Two", "Three", "Four");
return 0; }
Узнайте больше о многоточии и вариативных шаблонах в этой статье.
Стандартная библиотека шаблонов
В C++ встроено только несколько примитивных типов данных, в отличие от Python, который предоставляет динамический список, словарь, множество и кортежи и т. д.
Стандартная библиотека шаблонов (STL) — это программная библиотека для C++, которая предоставляет такие структуры данных и алгоритмы.
STL предоставляет следующие четыре компонента:
- Алгоритмы: поиск, сортировка и т. д.
- Контейнеры: последовательности, такие как вектор, список. Очередь, стек, карта, набор и т. д.
- Функции
- Итераторы
Она называется библиотекой шаблонов, потому что использует описанную выше функцию шаблонов C++.
Давайте посмотрим на один пример контейнера: вектор.
Вектор
Класс STL vector
— это шаблон класса для контейнеров последовательности.
Он хранит элементы заданного типа в линейном порядке и обеспечивает быстрый произвольный доступ к любому элементу. Похоже на массив? Да, это массив, но он динамический, т. е. его размер может изменяться при необходимости.
В этом примере показано, как создать и использовать вектор:
#include <iostream> #include <vector> // STL Header file for vector class
int main() { std::vector<int> numbers{1, 2, 3, 4, 5};
for (int i = 0; i < numbers.size(); i++) std::cout << numbers[i] << " "; std::cout << "\n"; // OUTPUT: 1 2 3 4 5
std::vector<char> alphabets; // Empty vector alphabets.push_back('a'); // adding an element to back of vector alphabets.push_back('b'); alphabets.push_back('c');
std::cout << alphabets[1] << "\n"; // OUTPUT: b
return 0; }
Чтобы узнать больше о STL, ознакомьтесь с этой статьей.
Цикл на основе диапазона
В предыдущем примере мы использовали простой цикл for для перебора нашего вектора. Мы можем сделать то же самое с лучшим циклом for на основе диапазона.
Синтаксис:
for (for-range-declaration : expression)
statement
Итак, вот как мы можем изменить предыдущий код с помощью цикла for на основе диапазона:
// For printing the numbers vector for (int x : numbers) std::cout << x << " ";
// For printing the alphabets vector for (auto ch : alphabets) // Notice the use of auto - Recommended std::cout << ch << " ";
for (auto i : {1, 2, 3}) std::cout << i << " "; // 1 2 3
int arr[] = {4, 5, 6}; for (auto j : arr) std::cout << j << " "; // 4 5 6
Здесь x
будет указывать на отдельный элемент в numbers
один за другим.
Чтобы узнать больше о циклах на основе диапазона, прочитайте эту статьюe.
Лямбда-выражения
Лямбда-выражение — это удобный способ определения анонимной функции.
Лямбда-выражения используются для инкапсуляции нескольких строк кода, которые передаются алгоритмам и другим функциям.
Синтаксис:
предложение захвата. Указывает, какие переменные захватываются из окружающей области, а также по значению или по ссылке.
- Переменные с префиксом & доступны по ссылке, другие по значению.
- Пустое предложение
[ ]
указывает, что лямбда-тело не имеет доступа к переменным в охватывающей области. [&]
означает, что все переменные захватываются по ссылке.[=]
означает, что все переменные фиксируются по значению.
список параметров (необязательно): лямбда-выражение может принимать входные параметры, как обычная функция. Это необязательно, и вы можете оставить круглые скобки пустыми, если параметры отсутствуют.
изменяемая спецификация (необязательно): ключевое слово mutable
позволяет нам изменять значение, полученное в теле лямбда-выражения. (Использование показано в примере ниже).
спецификация-исключения(необязательно): вы можете использовать спецификацию исключения noexcept
, чтобы указать, что лямбда-выражение не создает никаких исключений.
trailing-return-type (необязательно): как и обычная функция, лямбда также имеет возвращаемый тип. Вы можете опустить возвращаемую часть лямбда-выражения, если тело лямбда-выражения содержит только один оператор возврата или выражение не возвращает значение.
тело лямбда: тело лямбда может содержать все, что может содержать тело обычной функции.
Вот несколько примеров лямбда-функций:
- Здесь мы использовали лямбда-функцию, которая находит квадрат числа. Тип лямбды автоматически выводится с помощью auto и сохраняется в идентификаторе
square
. Тип возвращаемого значения автоматически выводится какint
.
#include <iostream> int main() { auto square = [](int n) { return n * n; }; std::cout << "Square of 2 = " << square(2) << "\n"; // Square of 2 = 4 return 0; }
- Здесь мы показали использование ключевого слова
mutable
, без него мы получили бы сообщение об ошибке, говорящее, чтоouter
доступно только для чтения. Более того, значениеouter
не изменилось за пределами лямбды, поскольку оно было захвачено значением[=]
.
#include <iostream> int main() { int outer = 50; auto fn = [=]() mutable { outer = 100; // OK, because of mutable std::cout << "Outer = " << outer << "\n"; // Outer = 100 }; fn(); std::cout << "Outer = " << outer << "\n"; // Outer = 50 return 0; }
- Здесь мы использовали лямбда для передачи функции алгоритму for_each.
#include <iostream> #include <algorithm> #include <vector> int main() { std::vector<int> nums{1, 2, 3, 4, 5, 6}; for (auto x : nums) // 1 2 3 4 5 6 std::cout << x << " "; std::cout << "\n"; // Square every number std::for_each(begin(nums), end(nums), [](int& n) {n = n * n;}); for (auto x : nums) // 1 4 9 16 25 36 std::cout << x << " "; std::cout << "\n"; return 0; }
Чтобы узнать больше о лямбда-функциях, ознакомьтесь с этой статьей.
EndNote
Эта статья должна была познакомить вас с некоторыми современными мощными функциями, предоставляемыми языком C++.
Если вы хотите узнать больше об этих функциях, вы можете перейти по ссылкам, предоставленным для каждой темы. Лучший способ узнать это — использовать его.
C++ обладает более удивительными и современными функциями, вопреки мнению, что это старый и устаревший язык.
Поделитесь своим мнением в комментариях.
Спасибо за чтение
Вам также может понравиться:
- Как создавать заголовочные файлы в C++
- Что происходит, когда вы запускаете компьютерную программу?
- Понимание в Python: объяснение
- Справочник по командам Linux с примерами
Эта статья была первоначально опубликована в Блоге Yuvraj’s CS.