Как вызвать лямбда-функцию с сообщением (M1) перед другим сообщением (M2), но на выходе должно быть «M2 M1»? - PullRequest
0 голосов
/ 24 марта 2019

Моя домашняя работа - реализовать функцию с именем finally, которая принимает процедуру с 0 аргументами и выполняет ее в конце текущей области.Я должен продемонстрировать его использование с помощью лямбда-выражения.После того как я создам лямбда-выражение, я должен назвать его прямо перед cout << "Hi" << endl;.

Вот что я придумал до сих пор:

#include "stdafx.h"
#include <iostream>

auto finally = []()
{
    std::cout << "Bye" << std::endl;
};

void test()
{
    finally();
    std::cout << "Hi" << std::endl;
}

int main(int argc, char const *argv[])
{
    test();
    std::cout << "End of Main" << std::endl;
    return 0;
}

Это выводит

Bye
Hi
End of Main

Тем не менее, окончательный результат должен быть:

Hi
Bye
End of Main

Как я могу поменять два сообщения, не перемещая finally() с его текущего места?

1 Ответ

0 голосов
/ 24 марта 2019

Обычная техника в c ++ - RAII . Вы создаете объект, который при разрушении будет выполнять какое-то действие. Обычно он будет что-то делать, когда создан, а также разрушен, но не обязательно.

Чтобы назвать типичный пример из стандартной библиотеки, std::ofstream закроет файл, с которым он связан, когда он будет уничтожен. Вы можете вручную вызвать close, но обычно это не требуется, поскольку он будет вызываться автоматически при уничтожении потока файлов.

Вы можете использовать ту же технику для вашего finally.

#include <iostream>

template <typename F>
class RAII {
    public:
    RAII(F f) : func(std::move(f)) {}
    ~RAII() { func(); }

    private:
    F func;
};

template <typename F>
auto finally(F f)
{
    return RAII<F>(std::move(f));
};

void test()
{
    auto raii_finally = finally([]{ std::cout << "Bye" << std::endl; });
    //RAII raii_finally([]{ std::cout << "Bye" << std::endl; }); <-- c++17
    std::cout << "Hi " << std::endl;
}

int main(int argc, char const *argv[])
{
    test();
    std::cout << "End of Main" << std::endl;
    return 0;
}

raii_finally разрушается в конце функции, и в деструкторе называется лямбда, которую мы передали.

В этом случае функция избыточна, и вы можете вызвать конструктор RAII напрямую, если используете c++17.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...