Современный C++ и альтернативы на C

Шаблоны в C++ и обобщённое программирование в C

В этом уроке вы напишете функцию для нескольких типов данных с помощью шаблонов C++ и сравните её с _Generic из C11.

Введение

Шаблоны (templates) позволяют написать обобщённую заготовку кода, по которой компилятор создаёт подходящую версию для каждого типа данных, сохраняя безопасность типов. В C для похожего результата обычно используют макросы, указатели void или ключевое слово _Generic из C11.

Главное

  • Поймите, как это делается в C, прежде чем изучать абстракции C++.
  • Выражайте владение ресурсами через RAII и семантику значений (value semantics).
  • Используйте типобезопасные средства C++ вместо макросов и приведений типов.

Примеры кода на C и C++

C
Запустить →
main.c
#include <stdio.h>

int max_int(int left, int right) {
    return left > right ? left : right;
}

double max_double(double left, double right) {
    return left > right ? left : right;
}

#define MAX(left, right) _Generic((left), \
    int: max_int, double: max_double)((left), (right))

int main(void) {
    printf("%d %.1f\n", MAX(3, 9), MAX(2.5, 7.0));
}
Результат выполнения
9 7.0
C++
Запустить →
main.cpp
#include <iostream>

template<class T>
T maximum(const T& left, const T& right) {
    return left > right ? left : right;
}

int main() {
    std::cout << maximum(3, 9) << ' '
              << maximum(2.5, 7.0) << '\n';
}
Результат выполнения
9 7

Сравнение C и C++

В C макрос MAX с помощью _Generic выбирает max_int или max_double в зависимости от типа аргумента, но все поддерживаемые типы приходится перечислять заранее. В C++ шаблон maximum работает с любым типом, который поддерживает сравнение >, без переписывания функции для каждого типа.

C

C использует соглашения об именах, обратные вызовы, макросы и struct с контекстом.

C++

C++ предлагает абстракции с чёткими границами, безопасные по типам и обычно без дополнительных затрат при выполнении.

Упражнения для практики

Запустите обе версии, а затем измените код, чтобы увидеть разницу в безопасности, которую даёт каждый язык.

  • Сначала напишите механизм на C, а затем используйте аналогичную возможность C++.
  • Замените ручное освобождение ресурсов на RAII.
  • Проверьте, не вызывает ли эта возможность выделение памяти или вызовы виртуальных функций.

Попрактикуйтесь на задаче

Примените материал этого урока к реальной задаче. Каждая задача запускается в браузере, с мгновенными тестами и разбором от ИИ.

Все задачи