Cleanup at unexpected function end, std equivalent

我与影子孤独终老i 提交于 2020-01-05 08:23:06

问题


I have some function where I need to use a member variable(a vector of custom classes).
At the end of this function this member needs to be cleared but it needs to stay as a member for the duration of this function. Another problem is that the function can end prematurely due to custom error handling of the program. Yet the member still needs to be cleared.

I first moved this member at the beginning in a local variable using std::move. This worked pretty well but it now turns out I need the variable to stay as a member variable till the end of that function.

I came up with the following solution using a unique_ptr with a reference that will do the move upon destruction.

#include <iostream>
#include <vector>
#include <memory>
using namespace std;

template <class T>
class Clean
{
public:
    Clean(T& clean)
        : m_clean(clean) {}
    ~Clean()
    {
        T destroy = move(m_clean);
    }
private:
    T& m_clean;
};

class A
{
public:
    A()
    {
        m_numbers = { { 3, 1 ,4, 1, 5} };
    }

    void display()
    {
        auto cleanNumbers = make_unique<Clean<vector<int> > >(m_numbers);
        for(int number: m_numbers)
            cout << number << endl;
    }
private:
    vector<int> m_numbers;
};

int main()
{
    A a;
    a.display();
    cout << "should be empty now" << endl;
    a.display();
    return 0;
}

Any cleaner solutions are also welcome but my actual question is the following.
Is there any std equivalent of the Clean class I used?

Ps: code fragment compiles for me using g++ 5.3.0

g++ -std=c++14 -o main main.cpp


回答1:


This is the result I came to thanks to comments and other questions:

void display()
{
    auto cleanNumber = [](decltype(m_numbers)* numbers){ 
        if(numbers) 
            numbers->clear();
    };
    auto pClean = std::unique_ptr<decltype(m_numbers), decltype(cleanNumber)>(&m_numbers, cleanNumber);
    for(int number: m_numbers)
        cout << number << endl;
}



回答2:


You could use a shared_ptr's custom deleter to obtain the same result.

void A::display()
{
    std::shared_ptr<int> dummy (
        (int*)alloca(sizeof(int)),                 // very fast allocate on stack
        [&](int*) { this->m_numbers.clear(); }
    );

    for(int number: m_numbers)
        cout << number << endl;
}

Here is the entire code, compiles fine, gcc 5.3 -Wall -Wpedantic -march=native -std=c++14

#include <iostream>
#include <vector>
#include <memory>
using namespace std;

class A
{
public:
    A()
    {
        m_numbers = { { 3, 1 ,4, 1, 5} };
    }

    void display()
    {
        std::shared_ptr<int> dummy (
            (int*)alloca(sizeof(int)),
            [&](int*) { this->m_numbers.clear(); }
        );

        for(int number: m_numbers)
            cout << number << endl;
    }
private:
    vector<int> m_numbers;
};

int main()
{
    A a;
    a.display();
    cout << "should be empty now" << endl;
    a.display();
    return 0;
}


来源:https://stackoverflow.com/questions/45162233/cleanup-at-unexpected-function-end-std-equivalent

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!