DevX Home    Today's Headlines   Articles Archive   Tip Bank   Forums   

Results 1 to 5 of 5

Thread: shared_ptr setting deleter function to include the guarded ptr

  1. #1
    Join Date
    Jan 2008
    Posts
    100

    shared_ptr setting deleter function to include the guarded ptr

    Hello all.

    I have been playing with std::tr1::shared_ptr to see if I can keep up-to-date.

    I very much like the way that it is easy to specify a custom deleter which makes it great for RAII with C libraries too. However if the cleanup function requires two parameters, I cannot seem to find out a way to send that into the reset function along with the other parameter(s). I use std::tr1::bind to attach a variable amount of arguments to the cleanup function.

    Code:
    #include <functional>
    #include <algorithm>
    #include <tr1/memory>
    #include <tr1/functional>
    
    void closeit(int otherRequirement, std::ifstream* f)
    {
      std::cout << "I run at least..." << std::endl;
      std::cout << "otherRequirement: " << otherRequirement << std::endl;
      std::cout << "ifstream: " << f << std::endl;
    
      // Cleanup using both parameters will happen here.
    }
    
    int main(int argc, char* argv[])
    {
      std::tr1::shared_ptr<std::ifstream> ptr;
    
      std::cout << "Hello World!" << std::endl;
    
      ptr.reset<std::ifstream>(new std::ifstream("test.txt"), std::tr1::bind(closeit, 1234, ptr.get()));
    
      return 0;
    }
    If you run this code, you will notice that the deleter function has a NULL pointer to the ifstream because I have tried to pass it in *whilst* also creating it so it has not yet been set in the shared_ptr yet.

    To put this into context, some C libraries require two parameters to clean up stuff, such as OpenGL's glFreeTexture(int, int), libpng's free_image_info and also a couple of X11 functions (Passing in Display* for most of them as well). So this is what the std::ifstream and 1234 represent. I just put these as examples so that everyone can easily compile it without these libraries installed.

    I would be interested in anyone's views or suggestions to this.

    Karsten
    Last edited by kpedersen; 09-22-2011 at 02:07 PM.

  2. #2
    Join Date
    Dec 2007
    Posts
    401
    The shared_ptr<> deleter is a unary function.

    The result of std::tr1::bind( closeit, 1234, ptr.get() ) is a nullary function. The first argument of closeit is bound to 1234. And the second argument is bound to the result of ptr.get() which is a nullptr (ptr was default-constructed).

    You should be binding only the extra argument. For example:
    Code:
    #include <algorithm>
    #include <memory>
    #include <iostream>
    
    struct A
    {
        A() { std::cout << "A::constructor\n" ; }
        ~A() { std::cout << "A::destructor\n" ; }
    } ;
    
    void deleter( int extra, A* pa )
    {
        std::cout << "extra: " << extra << "  pa: " << pa << " - " ;
        delete pa ;
    }
    
    int main()
    {
        std::shared_ptr<A> pa ;
        pa.reset<A>( new A, std::bind( deleter, 1234, std::placeholders::_1 ) ) ;
    }

  3. #3
    Join Date
    Jan 2008
    Posts
    100
    Oh wow. I don't think I have come across anything like this before.

    So specifying std::placeholders::_1 would effectively pass into the deleter function, the parameter (in this case the pointer to call delete on) that was the default if std::bind was not used and I instead had just passed in a function pointer.

    Thanks a lot for this vijayan, it is exactly what I needed.

    If I called ::bind a second time.. could I effectively do...
    Code:
    std::bind( deleter, std::placeholders::_1, std::placeholders::_2 )
    To just send in the same parameters again?

    I am going to have to experiment ;)

  4. #4
    Join Date
    Dec 2007
    Posts
    401
    Quote Originally Posted by kpedersen View Post
    If I called ::bind a second time.. could I effectively do...
    Code:
    std::bind( deleter, std::placeholders::_1, std::placeholders::_2 )
    To just send in the same parameters again?
    Yes. std::bind is very flexible. So is std::function<>.
    Code:
    #include <functional>
    #include <iostream>
    
    void foo( int a, int b, int c )
    { std::cout << "foo( " << a << ", " << b << ", " << c << " )\n" ; }
    
    int main()
    {
        using namespace std::placeholders ;
    
        std::function< void(int,int,int) > f1 = foo ;
        f1(1,2,3) ; // foo( 1, 2, 3 ) ;
    
        std::function< void(int,int,int) > f2 = std::bind( foo, _2, _3, _1 ) ;
        f2(1,2,3) ; // foo( 2, 3, 1 ) ;
    
        std::function< void(int,int) > f3 = std::bind( f1, _1, 99, _2 ) ;
        f3(1,2) ; // foo( 1, 99, 2 ) ;
    
        std::function< void(int) > f4 = std::bind( f3, _1, _1 ) ;
        f4(1) ; // foo( 1, 99, 1 ) ;
    
        std::function< void() > f5 = std::bind( f4, 47 ) ;
        f5() ; // foo( 47, 99, 47 ) ;
    }
    Last edited by vijayan; 09-23-2011 at 05:51 PM.

  5. #5
    Join Date
    Jan 2008
    Posts
    100
    Certainly seems powerful and I don't think I have seen any other language which supports this.

    However I imagine that it could get confusing pretty fast, so I will probably only this as part of RAII with shared_ptr.
    Although it looks as though it could also have a good use in callbacks for GUI components etc... (on newer c++ compilers)

    Thanks again.

Similar Threads

  1. syntax error from function in include file
    By larryy@indiana. in forum ASP.NET
    Replies: 1
    Last Post: 03-20-2009, 01:29 PM
  2. Excel VBA - Setting And Using Function Keys
    By Hack in forum VB Classic
    Replies: 2
    Last Post: 10-11-2008, 01:26 PM
  3. Getting a GUI to run
    By Eric in forum Java
    Replies: 4
    Last Post: 04-14-2006, 09:09 AM
  4. Replies: 2
    Last Post: 08-16-2000, 10:21 PM
  5. Replies: 0
    Last Post: 08-16-2000, 09:36 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
HTML5 Development Center
 
 
FAQ
Latest Articles
Java
.NET
XML
Database
Enterprise
Questions? Contact us.
C++
Web Development
Wireless
Latest Tips
Open Source


   Development Centers

   -- Android Development Center
   -- Cloud Development Project Center
   -- HTML5 Development Center
   -- Windows Mobile Development Center