Search code examples
c++boost-bindatexit

Passing values to atexit


I want to push a series of clean up functions as they are needed. I was using atexit to do this for one cleanup function without any parameters, but I am not sure how to expand this approach to more then one clean up function. I am not very familiar with boost::bind, but assumed it would be a good idea as that is how I binded my functions to threads...

In c++ I am trying to get the following to work:

Function Definition

static void closeAnimation(string prefix="");// static member of fileWriter

Code:

atexit(boost::bind(fileWriter::closeAnimation, "0")); // I want to first prefix to be "0"

The error:

cannot convert ‘boost::_bi::bind_t<void, void (*)(std::basic_string<char>), boost::_bi::list1<boost::_bi::value<const char*> > >’ to ‘void (*)()’ for argument

Thanks in advance!


Solution

  • There is no "1 line solution without complicating your code".

    The worst solution is to store that parameter in a global variable, and retrieve it in the atexit handler

    Since you're using C++, the destructor of a static variable could also serve as an atexit handler. Then you can pass parameter at the constructor of that static variable for parametrization, e.g.

    struct AtExitAnimationCloser
    {
        const char* _which_param;
    
        AtExitAnimationCloser(const char* which_param) : _which_param(which_param) {}
        ~AtExitAnimationCloser() { FileWriter::closeAnimation(_which_param); }
    };
    
    void f()
    {
        printf("entering f\n");
    
        static AtExitAnimationCloser s0 ("0"); // registers closeAnimation("0") at exit
        static AtExitAnimationCloser s1 ("1"); // registers closeAnimation("1") at exit
    
        printf("leaving f\n");
    }
    

    Demonstration: http://www.ideone.com/bfYnY

    Note that static variables are bound to their name, so you cannot say

    for (it = vecs.begin(); it != vecs.end(); ++ it)
    {
       static AtExitAnimationCloser s (*it);
    }
    

    to call atexit for all the content. But you could make the static variable itself take whole range

    static AnotherAtExitAnimationCloser s (vecs.begin(), vecs.end())
    

    Finally, with idiomatic C++ I don't think you need to use these tricks... You could store a vector of types T, which on destruction ~T calls fileWriter::closeAnimation.