passing ref to ptr again as ref to ptr....

Discussion in 'C++' started by osama178@gmail.com, Apr 24, 2008.

  1. Guest

    Let's say I have this code

    --------------------
    class GenericQueue
    {
    public:
    bool Pop(void*& refToPtr); //--------------(1)

    };

    class SpecialQueue: private GenericQueue
    {
    public:
    bool Pop(T*& refToPtr)
    {
    return
    GenericQueue::pop(refToPtr); //--------------------(2)
    }

    };

    Why does the statement in (2) generate an error?
     
    , Apr 24, 2008
    #1
    1. Advertising

  2. Bo Persson Guest

    wrote:
    > Let's say I have this code
    >
    > --------------------
    > class GenericQueue
    > {
    > public:
    > bool Pop(void*& refToPtr); //--------------(1)
    >
    > };
    >
    > class SpecialQueue: private GenericQueue
    > {
    > public:
    > bool Pop(T*& refToPtr)
    > {
    > return
    > GenericQueue::pop(refToPtr); //--------------------(2)
    > }
    >
    > };
    >
    > Why does the statement in (2) generate an error?


    You just cannot convert a reference to one type into a refererence to
    another type, unless the latter is a base class of the first.

    There is no guarantee that all T* must be the same size as a void*.


    Bo Persson
     
    Bo Persson, Apr 24, 2008
    #2
    1. Advertising

  3. Guest

    On Apr 24, 2:32 pm, "Bo Persson" <> wrote:
    > wrote:
    > > Let's say I have this code

    >
    > > --------------------
    > > class GenericQueue
    > > {
    > > public:
    > > bool Pop(void*& refToPtr); //--------------(1)

    >
    > > };

    >
    > > class SpecialQueue: private GenericQueue
    > > {
    > > public:
    > > bool Pop(T*& refToPtr)
    > > {
    > > return
    > > GenericQueue::pop(refToPtr); //--------------------(2)
    > > }

    >
    > > };

    >
    > > Why does the statement in (2) generate an error?

    >
    > You just cannot convert a reference to one type into a refererence to
    > another type, unless the latter is a base class of the first.
    >
    > There is no guarantee that all T* must be the same size as a void*.
    >
    > Bo Persson



    Does that mean references and templates are not to be mixed?
    And
    is that why STL containers do not store references to objects?
     
    , Apr 24, 2008
    #3
  4. Bo Persson Guest

    wrote:
    > On Apr 24, 2:32 pm, "Bo Persson" <> wrote:
    >> wrote:
    >>> Let's say I have this code

    >>
    >>> --------------------
    >>> class GenericQueue
    >>> {
    >>> public:
    >>> bool Pop(void*& refToPtr); //--------------(1)

    >>
    >>> };

    >>
    >>> class SpecialQueue: private GenericQueue
    >>> {
    >>> public:
    >>> bool Pop(T*& refToPtr)
    >>> {
    >>> return
    >>> GenericQueue::pop(refToPtr); //--------------------(2)
    >>> }

    >>
    >>> };

    >>
    >>> Why does the statement in (2) generate an error?

    >>
    >> You just cannot convert a reference to one type into a refererence
    >> to another type, unless the latter is a base class of the first.
    >>
    >> There is no guarantee that all T* must be the same size as a void*.
    >>
    >> Bo Persson

    >
    >
    > Does that mean references and templates are not to be mixed?


    No, they work very well together. I think the void* is the problem
    here, and that you are trying too hard to optimize the code.

    I would trust my compiler here, and just write

    template<class T>
    class GenericQueue
    {
    bool Pop(T&);

    };

    if that is the interface needed (it probably is not - take a look at
    std::queue and std::stack).

    The compiler knows which types (pointers or not) are of the same size,
    and can compile that to identical code.


    > And
    > is that why STL containers do not store references to objects?


    Many containers will have to copy some of their contents when
    inserting or erasing members. References cannot be copied.


    Bo Persson
     
    Bo Persson, Apr 24, 2008
    #4
  5. James Kanze Guest

    On Apr 24, 11:53 pm, "Bo Persson" <> wrote:
    > wrote:


    [...]
    > > Does that mean references and templates are not to be mixed?


    > No, they work very well together. I think the void* is the
    > problem here, and that you are trying too hard to optimize the
    > code.


    > I would trust my compiler here, and just write


    > template<class T>
    > class GenericQueue
    > {
    > bool Pop(T&);
    > };


    Given that he requires pointer semantics, and copying a pointer
    cannot throw, there's no reason not to just use
    T* pop() ;
    in the generic interface.

    > if that is the interface needed (it probably is not - take a
    > look at std::queue and std::stack).


    There's a slight difference. The standard containers are
    designed to store values, not (only) pointers. So the
    alternatives are:

    -- return a T, but not be thread safe,

    -- take a reference as a parameter, requiring the client to
    define (and construct) and instance before hand, or

    -- separate accessing the object and removing it, putting them
    in two separate functions.

    Globally, I think the first alternative was dismissed because of
    the lack of thread safety (although I think it was what was used
    in the original STL); of the latter two, the last seems to offer
    the most flexibility, and was chosen.

    If you limit elements in the container to types which cannot
    throw when being copied, then the first is the obvious solution.

    > The compiler knows which types (pointers or not) are of the
    > same size, and can compile that to identical code.


    Almost none do.
    And that's not the only point---you don't want to load your
    header files with complicated implementations, increasing
    coupling and compile times. In the absense of export, you may
    want to factorize the implementation into a non-generic part
    simply to reduce coupling.

    > > And is that why STL containers do not store references to
    > > objects?


    > Many containers will have to copy some of their contents when
    > inserting or erasing members. References cannot be copied.


    More to the point, the STL uses value semantics by default (as
    does the rest of C++). If the STL stored a reference, would
    that mean that the client code would have to ensure the
    lifetime of the object? I don't think storing references is a
    good idea, myself.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
     
    James Kanze, Apr 28, 2008
    #5
  6. gpderetta Guest

    On Apr 28, 11:12 am, James Kanze <> wrote:
    > On Apr 24, 11:53 pm, "Bo Persson" <> wrote:
    >
    > > wrote:

    >
    > [...]
    >
    > > > Does that mean references and templates are not to be mixed?

    > > No, they work very well together. I think the void* is the
    > > problem here, and that you are trying too hard to optimize the
    > > code.
    > > I would trust my compiler here, and just write
    > > template<class T>
    > > class GenericQueue
    > > {
    > > bool Pop(T&);
    > > };

    >
    > Given that he requires pointer semantics, and copying a pointer
    > cannot throw, there's no reason not to just use
    > T* pop() ;
    > in the generic interface.
    >
    > > if that is the interface needed (it probably is not - take a
    > > look at std::queue and std::stack).

    >
    > There's a slight difference. The standard containers are
    > designed to store values, not (only) pointers. So the
    > alternatives are:
    >
    > -- return a T, but not be thread safe,
    >
    > [...]
    > Globally, I think the first alternative was dismissed because of
    > the lack of thread safety (although I think it was what was used
    > in the original STL); of the latter two, the last seems to offer
    > the most flexibility, and was chosen.
    >


    IIRC, it had more to do with exception safety: if the copy constructor
    throws an exception when returning the pop'd object, you will lose
    the
    object with no way to recover it (it has already been removed from
    the
    internal queue). There is no such a problem with the
    separated 'T&top()' and 'void pop()'

    HTH,

    --
    gpd
     
    gpderetta, Apr 28, 2008
    #6
  7. James Kanze Guest

    On Apr 28, 12:17 pm, gpderetta <> wrote:
    > On Apr 28, 11:12 am, James Kanze <> wrote:
    > > On Apr 24, 11:53 pm, "Bo Persson" <> wrote:


    > > > wrote:


    > > [...]


    > > > > Does that mean references and templates are not to be mixed?
    > > > No, they work very well together. I think the void* is the
    > > > problem here, and that you are trying too hard to optimize the
    > > > code.
    > > > I would trust my compiler here, and just write
    > > > template<class T>
    > > > class GenericQueue
    > > > {
    > > > bool Pop(T&);
    > > > };


    > > Given that he requires pointer semantics, and copying a pointer
    > > cannot throw, there's no reason not to just use
    > > T* pop() ;
    > > in the generic interface.


    > > > if that is the interface needed (it probably is not - take a
    > > > look at std::queue and std::stack).


    > > There's a slight difference. The standard containers are
    > > designed to store values, not (only) pointers. So the
    > > alternatives are:


    > > -- return a T, but not be thread safe,


    > > [...]
    > > Globally, I think the first alternative was dismissed because of
    > > the lack of thread safety (although I think it was what was used
    > > in the original STL); of the latter two, the last seems to offer
    > > the most flexibility, and was chosen.


    > IIRC, it had more to do with exception safety: if the copy
    > constructor throws an exception when returning the pop'd
    > object, you will lose the object with no way to recover it (it
    > has already been removed from the internal queue). There is
    > no such a problem with the separated 'T&top()' and 'void
    > pop()'


    Yes. I don't know why I wrote thread---the issue was definitely
    exceptions, and the impossibility to offer a strong guarantee.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
     
    James Kanze, Apr 29, 2008
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Sid
    Replies:
    5
    Views:
    1,084
  2. Heiko Vogel
    Replies:
    3
    Views:
    565
    Method Man
    Sep 14, 2004
  3. franco ziade

    const ptr to const ptr ?

    franco ziade, Feb 17, 2005, in forum: C Programming
    Replies:
    3
    Views:
    402
    franco ziade
    Feb 17, 2005
  4. Replies:
    0
    Views:
    345
  5. Replies:
    22
    Views:
    768
    peter koch
    Apr 30, 2008
Loading...

Share This Page