Fine, make it move-constructible (only)

To satisfy some compilers.
And might as well reinstate that test case.
This commit is contained in:
Herb Sutter 2021-02-24 16:49:57 -08:00
parent f59cb795a0
commit 020ddc40c5
2 changed files with 27 additions and 2 deletions

View File

@ -52,14 +52,20 @@ template <class F>
class final_action class final_action
{ {
public: public:
explicit final_action(F f_) : f(f_) { } explicit final_action(F f_) : f(std::move(f_)) { }
~final_action() { f(); } ~final_action() { if (invoke) f(); }
final_action(final_action&& other)
: f(std::move(other.f)), invoke(std::exchange(other.invoke, false))
{ }
final_action(const final_action& rhs) = delete; final_action(const final_action& rhs) = delete;
final_action& operator=(const final_action&) = delete; final_action& operator=(const final_action&) = delete;
final_action& operator=(final_action&& other) = delete;
private: private:
F f; F f;
bool invoke = true;
}; };
// finally() - convenience function to generate a final_action // finally() - convenience function to generate a final_action

View File

@ -51,6 +51,25 @@ TEST(utils_tests, finally_lambda)
EXPECT_TRUE(i == 1); EXPECT_TRUE(i == 1);
} }
TEST(utils_tests, finally_lambda_move)
{
int i = 0;
{
auto _1 = finally([&]() { f(i); });
{
auto _2 = std::move(_1);
EXPECT_TRUE(i == 0);
}
EXPECT_TRUE(i == 1);
{
auto _2 = std::move(_1);
EXPECT_TRUE(i == 1);
}
EXPECT_TRUE(i == 1);
}
EXPECT_TRUE(i == 1);
}
TEST(utils_tests, finally_const_lvalue_lambda) TEST(utils_tests, finally_const_lvalue_lambda)
{ {
int i = 0; int i = 0;