Boost logo

Boost Users :

From: Travis Parks (jehugaleahsa_at_[hidden])
Date: 2006-12-01 23:57:35


Hello:
I just started using some boost today. I am trying to use a non-static
member function as the deleter in a shared_ptr. I was looking at the
source code and I don't think it is supported. This is what I had:

shared_ptr<Environment> environment(Environment::createEnvironment(),
    Environment::terminateEnvironment);
string userName = "monkey_bottoms";
string password = "blahblahblah"
shared_ptr<Connection> connection(
    environment->createConnection(
        userName,
        password),
    &Environment::terminateConnection);

This didn't work at all! When I looked at the source I saw why. Note
that Environment::terminateConnection is a static method. However,
this source works fine for the static Environment::createEnvironment
method.

I am working in Visual Studio 8 with the OCCI. For the time being, I
have made a temporary solution. I am hoping someone can help me find a
less customized solution. Plus, I am thinking having a pointer to an
object that I am trying to manage kind of defeats the point. Here you
go:

#include "occi.h"
#include <boost/shared_ptr.hpp>
#include <string>
#include <functional>

// retarded temporary solution
template <class TCLASS, class TRETURN, class TARG>
class call_redirect_t : public std::unary_function<TARG, TRETURN>
{
    TCLASS * instance; // barf I have a pointer to a managed resource!
    TRETURN (TCLASS::*func) (TARG);
public:
    call_redirect_t(TCLASS * instance, TRETURN (TCLASS::*func) (TARG))
        : instance(instance),
        func(func)
    {
    }

    TRETURN operator()(TARG arg)
    {
        return (instance->*func)(arg);
    }
};

// convenience function
template <class TCLASS, class TRETURN, class TARG>
call_redirect_t<TCLASS, TRETURN, TARG> call_redirect(TCLASS *
instance, TRETURN (TCLASS::*func)(TARG))
{
    return call_redirect_t<TCLASS, TRETURN, TARG>(instance, func);
}

int main(int argc, char * argv[])
{
    // lazy
    using namespace std;
    using namespace oracle::occi;
    using namespace boost;

    shared_ptr<Environment> environment(
        Environment::createEnvironment(), // gets Environment *
        Environment::terminateEnvironment); // static method
    string userName = "flipflop";
    string password = "memoryrizor";
    shared_ptr<Connection> connection(
        environment->createConnection(userName, password), // gets Connection *
        call_redirect(
             environment.get(), // pull the pointer out; instant poo
             &Environment::terminateConnection) // non-static method
        );
}

Well, now that I think about it; since the temporary call_redirect
will only exist in the scope of the shared_ptr (who handles my
resource) it doesn't matter that I let it go, and parameter evaluation
order is not an issue.

Take a look at the operator() in call_redirect_t. I had to put
parenthesis around:
    (instance->*func)
I am think I have forgotten the syntax. Hmph. Weep, I am not perfect.

Thanks for any input, folks.

Travis Parks


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net