Learning auto_ptr_ref role in auto_ptr implementation

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • dragoncoder

    #1

    Learning auto_ptr_ref role in auto_ptr implementation

    Hi all,

    I am trying to understand the auto_ptr_ref role in the implementation
    of auto_ptr<>. I read the information on net but still not 100% sure of
    it. My plan is as follows.

    1. To see the behaviour of std::auto_ptr.
    2. To implement a pkt::auto_ptr without auto_ptr_ref.
    3. Check out the limitations of pkt::auto_ptr as compared to
    std::auto_ptr (using steps 1 and 2).
    4. Try to relate the concept of auto_ptr_ref to fill the gaps found in
    step 3.

    NOTE: Any siggestions on this are welcome.

    As the first step I have written the following program.

    =cat example.cxx
    #include <iostream>
    #include <memory>

    using namespace std;

    template <typename T>
    auto_ptr <Tsource ( T a )
    {
    return auto_ptr <T( new T ( a ) );
    }

    template <typename T>
    void print ( /* const */ auto_ptr <T>& p )
    {
    cout << "In print(): " << *p << endl;
    }

    int main()
    {
    print ( source ( 5 ) );
    return 0;
    }

    z852378@premier :/home/z852378/rnd/pkt
    =g++ example.cxx
    example.cxx: In function `int main()':
    example.cxx:20: could not convert `source(T) [with T = int]()' to `
    std::auto_ptr<i nt>&'
    example.cxx:14: in passing argument 1 of `void print(std::auto _ptr<T>&)
    [with T
    = int]'

    Uncommenting the 'const' in print() definition compiles the code fine
    and the output is also fine. Based on my current knowledge, this is
    because the return value of source() is a temporary and therefore can
    not be bound to a non-const reference. Is my understanding correct ?

  • dasjotre

    #2
    Re: Learning auto_ptr_ref role in auto_ptr implementation


    dragoncoder wrote:
    Hi all,
    >
    I am trying to understand the auto_ptr_ref role in the implementation
    of auto_ptr<>. I read the information on net but still not 100% sure of
    it. My plan is as follows.
    >
    1. To see the behaviour of std::auto_ptr.
    2. To implement a pkt::auto_ptr without auto_ptr_ref.
    3. Check out the limitations of pkt::auto_ptr as compared to
    std::auto_ptr (using steps 1 and 2).
    4. Try to relate the concept of auto_ptr_ref to fill the gaps found in
    step 3.
    >
    NOTE: Any siggestions on this are welcome.
    >
    As the first step I have written the following program.
    >
    =cat example.cxx
    #include <iostream>
    #include <memory>
    >
    using namespace std;
    >
    template <typename T>
    auto_ptr <Tsource ( T a )
    {
    return auto_ptr <T( new T ( a ) );
    }
    >
    template <typename T>
    void print ( /* const */ auto_ptr <T>& p )
    {
    cout << "In print(): " << *p << endl;
    }
    >
    int main()
    {
    print ( source ( 5 ) );
    return 0;
    }
    >
    z852378@premier :/home/z852378/rnd/pkt
    =g++ example.cxx
    example.cxx: In function `int main()':
    example.cxx:20: could not convert `source(T) [with T = int]()' to `
    std::auto_ptr<i nt>&'
    example.cxx:14: in passing argument 1 of `void print(std::auto _ptr<T>&)
    [with T
    = int]'
    >
    Uncommenting the 'const' in print() definition compiles the code fine
    and the output is also fine. Based on my current knowledge, this is
    because the return value of source() is a temporary and therefore can
    not be bound to a non-const reference. Is my understanding correct ?
    yes.

    Comment

    • rani_sharoni@hotmail.com

      #3
      Re: Learning auto_ptr_ref role in auto_ptr implementation

      dragoncoder wrote:
      Hi all,
      >
      I am trying to understand the auto_ptr_ref role in the implementation
      of auto_ptr<>. I read the information on net but still not 100% sure of
      it. My plan is as follows.
      Here is the original suggestion for the current auto_ptr:


      Carefully read the "Analysis of Conversion operations" section.

      The following defect report on auto_ptr explains why the current
      auto_ptr is partially broken and suggests a fully working auto_ptr:


      Another interesting insight about auto_ptr, written by the most
      authorized C++ core expert:


      Although I wrote defect report #463 I personally prefer to avoid
      auto_ptr and to use policy based smart class *without* the copy w/
      transfer of ownership semantics.

      Rani

      Comment

      • mlimber

        #4
        Re: Learning auto_ptr_ref role in auto_ptr implementation

        dragoncoder wrote:
        I am trying to understand the auto_ptr_ref role in the implementation
        of auto_ptr<>. I read the information on net but still not 100% sure of
        it.
        Did you read and understand the links given in this post:



        If not, what is confusing you?

        Cheers! --M

        Comment

        • dragoncoder

          #5
          Re: Learning auto_ptr_ref role in auto_ptr implementation


          rani_shar...@ho tmail.com wrote:
          dragoncoder wrote:
          Hi all,

          I am trying to understand the auto_ptr_ref role in the implementation
          of auto_ptr<>. I read the information on net but still not 100% sure of
          it. My plan is as follows.
          >
          Here is the original suggestion for the current auto_ptr:

          >
          Carefully read the "Analysis of Conversion operations" section.
          >
          The following defect report on auto_ptr explains why the current
          auto_ptr is partially broken and suggests a fully working auto_ptr:

          >
          Another interesting insight about auto_ptr, written by the most
          authorized C++ core expert:

          >
          Although I wrote defect report #463 I personally prefer to avoid
          auto_ptr and to use policy based smart class *without* the copy w/
          transfer of ownership semantics.
          >
          Rani
          Thanks a lot for the references and it seems to me that these document
          will answer my questions. But I would really love to have a look at the
          changes done to auto_ptr since the beginning. I mean I want to know the
          reason of the change in auto_ptr from CD-1 to CD-2. Could you please
          give me some references on that ?

          Thanks in advance.

          Comment

          • dragoncoder

            #6
            Re: Learning auto_ptr_ref role in auto_ptr implementation

            Thanks everyone for the replies, I really appreciate it.

            I have the following piece of text from "The C++ Standard Library" by
            Nicolai Josuttis.

            ....
            The rest of the class auto_ptr (auxiliary type auto_ptr_ref and
            functions using it) consists of rather tricky conversions that enable
            you to use copy and assignment operations for nonconstant auto_ptrs but
            not for constant auto_ptrs...

            I hope they are talking about the auto_ptr_ref trick here, correct me
            if I am wrong. Anyways, this means it (the trick) enables me to use
            copy and assignment operators for non-const std::auto_ptr (with the
            help of auto_ptr_ref) but not for const auto_ptr. Now please look at
            the following code.

            // File pkt.h
            #ifndef _PKT_H
            #define _PKT_H

            namespace pkt
            {

            template <typename T>
            class auto_ptr
            {
            private:
            // member which points to the allocated memory
            T* ap;
            public:
            typedef T element_type;

            // parameterized constructor
            explicit auto_ptr ( T* p = 0 ) throw () : ap ( p ) { }

            // default copy constructor
            auto_ptr ( auto_ptr & a ) throw () : ap ( a.release() ) { }

            // copy constructor with implicit conversion
            template <typename Xauto_ptr ( auto_ptr <X>& a ) throw () : ap (
            a.release() ) { }

            // default assignment operator
            auto_ptr& operator= ( auto_ptr & a ) throw ()
            {
            reset ( a.release() );
            return *this;
            }

            // assignment operator with implicit conversion
            template <typename XT& operator= ( auto_ptr <X>& a ) throw ()
            {
            reset ( a.release() );
            return *this;
            }

            // destructor
            ~auto_ptr () throw ()
            {
            delete this->ap;
            }

            // returns the holder pointer
            T* get () const throw ()
            {
            return this->ap;
            }

            // returns the object as an lvalue
            T& operator* () const
            {
            return *(this->ap);
            }

            // returns the holder pointer
            T* operator-() const
            {
            return this->ap;
            }
            // returns the holder pointer after deleting it
            T* release () throw ()
            {
            T* tmp ( ap );
            ap = 0;
            return tmp;
            }

            // resets to the newly allocated memory
            void reset ( T* a = 0 ) throw ()
            {
            if ( ap != a )
            {
            delete this->ap;
            this->ap = a;
            }
            }

            }; // end class auto_ptr
            } // end namespace pkt

            #endif // end #ifndef

            // File pkt.cxx
            #include <iostream>
            #include <memory>
            #include "pkt.h"

            using std::cout;
            using std::endl;
            using pkt::auto_ptr;

            template <typename T>
            auto_ptr<Tsourc e ( T a )
            {
            return auto_ptr<T( new T ( ) );
            }

            template <typename T>
            void print ( auto_ptr<T>& a )
            {
            cout << "Inside print(): value passed is: " << *a << endl;
            }

            int main()
            {
            auto_ptr<intpi1 ( new int ( 10 ) );
            print ( pi1 ) ;
            const auto_ptr<intpi2 ( new int ( 20 ) );
            print ( pi2 );
            }

            =g++ pkt.cxx
            pkt.cxx: In function `int main()':
            pkt.cxx:26: no matching function for call to `print(const
            pkt::auto_ptr<i nt>&)'

            My point is that pkt::auto_ptr does not have any auto_ptr_ref trick but
            then also it is allowing me to use the copy and assignment operator for
            a non-const auto_ptr but not for const auto_ptr.

            My question is what was the problem which was being tried to solve
            using the auto_ptr_ref trick. An example would be much appreciated.

            Thanks in advance.

            Comment

            • dragoncoder

              #7
              Re: Learning auto_ptr_ref role in auto_ptr implementation

              I am totally lost with the readings that I have been doing, please help
              me out. I thought auto_ptr_ref was introduces so that its possible to
              return an std::auto_ptr from a function and copying it into another
              std::auto_ptr. This is the code I tried.

              =cat example.cxx
              #include <iostream>
              #include <memory>

              using namespace std;

              template <typename T>
              auto_ptr <Tsource ( const T &a )
              {
              return auto_ptr <T( new T ( a ) );
              }

              int main()
              {
              auto_ptr <intpi2;
              pi2 = source ( 5 );
              return 0;
              }

              =g++ pkt.cxx
              pkt.cxx: In function `int main()':
              pkt.cxx:27: no matching function for call to
              `pkt::auto_ptr< int>::auto_ptr(
              pkt::auto_ptr<i nt>)'
              pkt.h:23: candidates are: pkt::auto_ptr<T >::auto_ptr(pkt ::auto_ptr<X>&)
              [with X
              = int, T = int]
              pkt.h:20: pkt::auto_ptr<T >::auto_ptr(pkt ::auto_ptr<T>&)
              [with T
              = int]
              pkt.h:17: pkt::auto_ptr<T >::auto_ptr(T * = 0) [with T =
              int]
              pkt.cxx: In function `pkt::auto_ptr< Tsource(const T&) [with T =
              int]':
              pkt.cxx:27: instantiated from here
              pkt.cxx:12: no matching function for call to
              `pkt::auto_ptr< int>::auto_ptr(
              pkt::auto_ptr<i nt>)'
              pkt.h:23: candidates are: pkt::auto_ptr<T >::auto_ptr(pkt ::auto_ptr<X>&)
              [with X
              = int, T = int]
              pkt.h:20: pkt::auto_ptr<T >::auto_ptr(pkt ::auto_ptr<T>&)
              [with T
              = int]

              Based on what I have read, I expect the above code to get compiled. Can
              someone please explain if I am missing somerhing ?

              Thanks

              Comment

              • Alf P. Steinbach

                #8
                Re: Learning auto_ptr_ref role in auto_ptr implementation

                * dragoncoder:
                I am totally lost with the readings that I have been doing, please help
                me out. I thought auto_ptr_ref was introduces so that its possible to
                return an std::auto_ptr from a function and copying it into another
                std::auto_ptr. This is the code I tried.
                The error messages + your earlier postings indicate that it's absolutely
                /not/ the code you tried.

                [snip]

                - Alf

                --
                A: Because it messes up the order in which people normally read text.
                Q: Why is it such a bad thing?
                A: Top-posting.
                Q: What is the most annoying thing on usenet and in e-mail?

                Comment

                • dragoncoder

                  #9
                  Re: Learning auto_ptr_ref role in auto_ptr implementation

                  Alf P. Steinbach wrote:
                  * dragoncoder:
                  I am totally lost with the readings that I have been doing, please help
                  me out. I thought auto_ptr_ref was introduces so that its possible to
                  return an std::auto_ptr from a function and copying it into another
                  std::auto_ptr. This is the code I tried.
                  >
                  The error messages + your earlier postings indicate that it's absolutely
                  /not/ the code you tried.
                  I am extremely sorry, I seem to have lost my senses while trying to
                  understand this beast. But I think I have pretty much got the idea.
                  This is the code which compiles fine with std::auto_ptr but not with
                  pkt::auto_ptr, which shows the missing link between these 2, which I
                  think is auto_ptr_ref.

                  =cat example.cxx
                  #include <iostream>
                  #include <memory>

                  using namespace std;

                  template <typename T>
                  auto_ptr <Tsource ( const T &a )
                  {
                  return auto_ptr <T( new T ( a ) );
                  }

                  template <typename T>
                  void print ( auto_ptr <T>& p )
                  {
                  cout << "In print(): " << *p << endl;
                  }

                  int main()
                  {
                  auto_ptr <intpi2;
                  pi2 = source ( 5 );
                  print ( pi2 );
                  auto_ptr <intpi1 ( source ( 10 ) );
                  return 0;
                  }

                  I am really surprised how pi2 = source ( 5 ) working with the help of
                  auto_ptr_ref ( or for that matter auto_ptr <intpi1 ( source ( 5 ) )
                  ). Can someone please explain what is happening behind the scene ?

                  Thanks very much.

                  Comment

                  • rani_sharoni@hotmail.com

                    #10
                    Re: Learning auto_ptr_ref role in auto_ptr implementation

                    dragoncoder wrote:
                    >
                    I am really surprised how pi2 = source ( 5 ) working with the help of
                    auto_ptr_ref ( or for that matter auto_ptr <intpi1 ( source ( 5 ) )
                    ). Can someone please explain what is happening behind the scene ?
                    >
                    1) pi2 = source ( 5 );
                    The code compiles because of operator=(auto_ ptr_ref<T>) that was added
                    to allow usage like the one that you mentioned.

                    This assignment operator was a late addition for auto_ptr that has been
                    accepted to TC1:


                    2) const auto_ptr<int>& r = source(5)
                    The current standard requires a viable copy constructor in order to
                    bind a class rvalue (e.g. return value from function) to a const
                    reference since additional temporary might be involved.

                    The future standard will probably relax this (frustrating) requirement
                    to only allow direct binding, see:


                    My suggestion (DR #462) for fixing auto_ptr actually seems to allow
                    this case with many highly compliant compliers.

                    Notice that the copy semantics in C++ can be extremely subtle and there
                    are several simple examples for which even highly compliant compliers
                    completely disagree (sometimes even inconsistent them self).

                    Personally, I prefer regulate the code with facilities that have "less"
                    subtleties, are more syntactically/semantically robust and easier to
                    understand.

                    Rani

                    Comment

                    Working...