如何在另一个消息(M2)之前先用消息(M1)调用lambda函数,但输出为“ M2 M1”?

时间:2019-03-23 22:17:50

标签: c++ function lambda

我的工作是实现一个名为finally的函数,该函数接受一个带有0个参数的过程,并在当前作用域的末尾执行该过程。我应该通过使用lambda表达式来演示其用法。创建lambda表达式后,应在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 :(得分:0)

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在函数末尾被破坏,在析构函数中,我们传入的lambda被调用。

在这种情况下,该函数是多余的,如果使用RAII,则可以直接调用c++17的构造函数。