<MyRusakov.ru />

Создание игр на Unreal Engine 5

Создание игр на Unreal Engine 5

Данный курс научит Вас созданию игр на Unreal Engine 5. Курс состоит из 12 модулей, в которых Вы с нуля освоите этот движок и сможете создавать самые разные игры.

В курсе Вы получите всю необходимую теоретическую часть, а также увидите массу практических примеров. Дополнительно, почти к каждому уроку идут упражнения для закрепления материала.

Помимо самого курса Вас ждёт ещё 8 бесплатных ценных Бонусов: «Chaos Destruction», «Разработка 2D-игры», «Динамическая смена дня и ночи», «Создание динамической погоды», «Создание искусственного интеллекта для NPC», «Создание игры под мобильные устройства», «Создание прототипа RPG с открытым миром» и и весь курс «Создание игр на Unreal Engine 4» (актуальный и в 5-й версии), включающий в себя ещё десятки часов видеоуроков.

Подробнее
Подписка

Подпишитесь на мой канал на YouTube, где я регулярно публикую новые видео.

YouTube Подписаться

Подписавшись по E-mail, Вы будете получать уведомления о новых статьях.

Подписка Подписаться

Добавляйтесь ко мне в друзья ВКонтакте! Отзывы о сайте и обо мне оставляйте в моей группе.

Мой аккаунт Мой аккаунт Моя группа
Опрос

Какая тема Вас интересует больше?

std::pair и std::tuple в C++: как возвращать несколько значений из функции

std::pair и std::tuple в C++: как возвращать несколько значений из функции

Поисковый запрос, под который написана статья: как вернуть несколько значений из функции C++. Это частая задача: функция должна вернуть, например, минимальное и максимальное число, результат операции и сообщение об ошибке, координаты точки или несколько рассчитанных параметров. В C++ для этого удобно использовать std::pair, std::tuple и структурные привязки, появившиеся в C++17.

Почему нельзя просто вернуть несколько значений через return?

Оператор return возвращает одно значение. Но это одно значение может быть составным: объектом, структурой, парой или кортежем. Плохой вариант — использовать глобальные переменные или передавать всё через неконстантные ссылки без необходимости. Такой код сложнее читать и тестировать.

std::pair: когда нужно вернуть два значения

std::pair — это простой контейнер ровно для двух значений. Он находится в заголовке <utility>. Типы значений могут быть разными: например, int и std::string.

#include <iostream>
#include <utility>
#include <vector>

std::pair<int, int> findMinMax(const std::vector<int>& numbers) {
    int minValue = numbers[0];
    int maxValue = numbers[0];

    for (int x : numbers) {
        if (x < minValue) minValue = x;
        if (x > maxValue) maxValue = x;
    }

    return {minValue, maxValue};
}

int main() {
    std::vector<int> values = {7, 2, 10, 4};

    auto result = findMinMax(values);

    std::cout << "Минимум: " << result.first << "\n";
    std::cout << "Максимум: " << result.second << "\n";
}

У std::pair поля называются first и second. Это удобно для коротких примеров, но в большом коде такие имена не всегда понятны. Если пара означает «минимум и максимум», читателю приходится помнить порядок значений.

Structured bindings: аккуратная распаковка пары

Начиная с C++17, результат можно распаковать в переменные с понятными именами. Это делает код значительно читабельнее.

auto [minValue, maxValue] = findMinMax(values);

std::cout << minValue << " " << maxValue << "\n";

Такой подход особенно хорош для функций, которые возвращают небольшой набор связанных значений. Главное — не злоупотреблять: если значений много или у них сложный смысл, лучше создать отдельную структуру с именованными полями.

std::tuple: если значений больше двух

std::tuple похож на std::pair, но может хранить три, четыре и больше значений. Он находится в заголовке <tuple>. Например, функция парсинга может вернуть статус, число и текст ошибки.

#include <iostream>
#include <string>
#include <tuple>

std::tuple<bool, int, std::string> parseNumber(const std::string& text) {
    try {
        int value = std::stoi(text);
        return {true, value, ""};
    } catch (...) {
        return {false, 0, "Не удалось преобразовать строку в число"};
    }
}

int main() {
    auto [ok, value, error] = parseNumber("123");

    if (ok) {
        std::cout << "Число: " << value << "\n";
    } else {
        std::cout << "Ошибка: " << error << "\n";
    }
}

Без structured bindings пришлось бы использовать std::get<0>(result), std::get<1>(result) и так далее. Это работает, но читается хуже, особенно если порядок элементов неочевиден.

Когда лучше использовать struct вместо pair или tuple

std::pair и std::tuple удобны, но не всегда являются лучшим выбором. Если возвращаемые данные имеют важный предметный смысл, лучше объявить структуру. Имена полей будут документировать код сами по себе.

#include <string>

struct ParseResult {
    bool success;
    int value;
    std::string errorMessage;
};

ParseResult parseNumberBetter(const std::string& text) {
    try {
        return {true, std::stoi(text), ""};
    } catch (...) {
        return {false, 0, "Некорректное число"};
    }
}

Правило простое: pair используйте для двух очевидно связанных значений, tuple — для коротких технических результатов, struct — для данных, которые важны для бизнес-логики и будут использоваться в разных местах программы.

Практический пример: деление с проверкой ошибки

Допустим, нужно выполнить деление и вернуть не только результат, но и информацию об успехе операции. Для учебного примера подойдёт std::pair<bool, double>.

#include <iostream>
#include <utility>

std::pair<bool, double> safeDivide(double a, double b) {
    if (b == 0.0) {
        return {false, 0.0};
    }

    return {true, a / b};
}

int main() {
    auto [success, result] = safeDivide(10.0, 2.0);

    if (success) {
        std::cout << "Результат: " << result << "\n";
    } else {
        std::cout << "Ошибка: деление на ноль\n";
    }
}

В реальном проекте для отсутствующего результата часто лучше использовать std::optional или отдельный тип результата, но для понимания идеи возврата нескольких значений этот пример отлично подходит.

Типичные ошибки новичков

  • Путать порядок элементов. В tuple легко забыть, что лежит на позиции 0, 1 или 2. Если смысл неочевиден — создайте struct.
  • Возвращать слишком большой tuple. Кортеж из пяти-семи элементов почти всегда хуже именованной структуры.
  • Использовать pair ради всего подряд. first и second не объясняют предметную область.
  • Игнорировать пустые входные данные. В примере с минимумом и максимумом нужно отдельно обработать пустой вектор, если такая ситуация возможна.

Рекомендации

  • Для C++17 и новее используйте auto [a, b] = function(); — это короче и понятнее.
  • Не бойтесь возвращать объекты по значению: современные компиляторы хорошо оптимизируют такие возвраты.
  • Если результат функции — важная сущность, дайте ей имя через struct.
  • Подключайте только нужные заголовки: <utility> для pair, <tuple> для tuple.

Если вы хотите системно разобраться не только с pair, tuple и функциями, но и с фундаментом языка, практикой ООП, STL и современным C++, обратите внимание на пошаговый курс «Программирование на C++ с Нуля до Гуру». Он хорошо подходит тем, кто хочет учиться последовательно, а не собирать знания из случайных фрагментов.

Вывод

Чтобы вернуть несколько значений из функции C++, используйте std::pair для двух значений, std::tuple для небольшого набора значений и struct, когда данным нужны понятные имена. В современном C++ связка pair/tuple + structured bindings позволяет писать компактный, безопасный и читаемый код без лишних обходных решений.

Копирование материалов разрешается только с указанием автора (Михаил Русаков) и индексируемой прямой ссылкой на сайт (https://myrusakov.ru)!

Добавляйтесь ко мне в друзья ВКонтакте: https://vk.com/myrusakov.
Если Вы хотите дать оценку мне и моей работе, то напишите её в моей группе: https://vk.com/rusakovmy.

Если Вы не хотите пропустить новые материалы на сайте,
то Вы можете подписаться на обновления: Подписаться на обновления

Если у Вас остались какие-либо вопросы, либо у Вас есть желание высказаться по поводу этой статьи, то Вы можете оставить свой комментарий внизу страницы.

Порекомендуйте эту статью друзьям:

Если Вам понравился сайт, то разместите ссылку на него (у себя на сайте, на форуме, в контакте):

  1. Кнопка:

    Она выглядит вот так: Как создать свой сайт

  2. Текстовая ссылка:

    Она выглядит вот так: Как создать свой сайт

  3. BB-код ссылки для форумов (например, можете поставить её в подписи):

Комментарии (0):

Для добавления комментариев надо войти в систему.
Если Вы ещё не зарегистрированы на сайте, то сначала зарегистрируйтесь.