Ambiguity with Smart Pointers (Boost or similar)

Discussion in 'C++' started by number774@netscape.net, Jan 3, 2008.

  1. Guest

    I've used Boost for this example; in fact we have our own pointer
    class, for historic reasons.

    #include "boost\shared_ptr.hpp"

    // A heirarchy of classes
    class G1 {};
    class G2: public G1 {};

    // A method which takes a shared pointer to the base class
    void f(boost::shared_ptr<G1>) {};

    // A method which takes a shared pointer to some other class
    void f(boost::shared_ptr<int>) {};

    void main()
    {
    // Call a method with a shared pointer to a derived class
    f(boost::shared_ptr<G2>());
    }

    This fails, because the compiler is unable to decide which of the two
    methods is meant. Of course, to a human, it's pretty obvious which
    one is meant, but there doesn't seem to be enough information at the
    time for the compiler to decide. In practice I have several hundred
    functions, and 50 or so classes, to get confused among, so I don't
    really want to take the obvious route [declare an
    f(boost::shared_ptr<G2>) ]. Is there anything I can do to the pointer
    class, or even to the class inheritance, that'll help the compiler
    out?

    Thx
     
    , Jan 3, 2008
    #1
    1. Advertising

  2. kwikius Guest

    On 3 Jan, 12:11, wrote:
    > I've used Boost for this example;  in fact we have our own pointer
    > class, for historic reasons.
    >
    > #include "boost\shared_ptr.hpp"
    >
    > // A heirarchy of classes
    > class G1 {};
    > class G2: public G1 {};
    >
    > // A method which takes a shared pointer to the base class
    > void f(boost::shared_ptr<G1>) {};
    >
    > // A method which takes a shared pointer to some other class
    > void f(boost::shared_ptr<int>) {};
    >
    > void main()
    > {
    >         // Call a method with a shared pointer to a derived class
    >         f(boost::shared_ptr<G2>());
    >
    > }
    >
    > This fails, because the compiler is unable to decide which of the two
    > methods is meant.  Of course, to a human, it's pretty obvious which
    > one is meant, but there doesn't seem to be enough information at the
    > time for the compiler to decide.  In practice I have several hundred
    > functions, and 50 or so classes, to get confused among, so I don't
    > really want to take the obvious route [declare an
    > f(boost::shared_ptr<G2>) ].  Is there anything I can do to the pointer
    > class, or even to the class inheritance, that'll help the compiler
    > out?
    >
    > Thx


    I don't use boost::shared_ptr, but I am surprised if it cant
    discriminate the above case, though maybe this is the result of an old
    compiler, which may mean it cant use some facilities.

    Hint! use some SFINAE, in combination with std::tr1 type_traits, e.g
    is_base_of etc, but as I said a good smart pointer should easily
    handle this case automatically.

    regards
    Andy Little
     
    kwikius, Jan 3, 2008
    #2
    1. Advertising

  3. Guest

    On Jan 3, 12:57 pm, kwikius <> wrote:
    >
    > I don't use boost::shared_ptr, but I am surprised if it cant
    > discriminate the above case, though maybe this is the result of an old
    > compiler, which may mean it cant use some facilities.
    >


    Fails with MS VC 2005 AND Gcc 4.01 on an Apple...

    > Hint! use some SFINAE, in combination with std::tr1 type_traits, e.g
    > is_base_of etc, but as I said a good smart pointer should easily
    > handle this case automatically.


    If you know a better smart pointer, please let me know :) .
    Meanwhile, I'll keep playing. is_base_of isn't in my copy of the
    standard [2003, 2nd ed] but there are web refs to it in Boost which
    I'll read.

    Thanks
     
    , Jan 3, 2008
    #3
  4. kwikius Guest

    On 3 Jan, 13:39, wrote:
    > On Jan 3, 12:57 pm, kwikius <> wrote:
    >
    >
    >
    > > I don't use boost::shared_ptr, but I am surprised if it cant
    > > discriminate the above case, though maybe this is the result of an old
    > > compiler, which may mean it cant use some facilities.

    >
    > Fails with MS VC 2005 AND Gcc 4.01 on an Apple...


    Yep ... :) looking at the docs there is an unconstrained ctor:

    shared_ptr<T>::shared_ptr(shared_ptr<T1>))

    with documented requirements T1* must be convertible to T*.

    Because the param is unconstrained is why it fails!

    In an ideal world you could try changing this ctor to something like:

    template <typename T>
    template <typename Derived>
    shared_ptr<T>::shared_ptr(shared_ptr<Derived> const & in,
    typename quanta::where_<
    std::tr1::is_base_of<T,Derived>,
    void*
    >::type* =0

    ){...}

    (Not quite same as *convertible to* but near enough to start with, and
    then your O.P. code should work OK.

    Of course you probably arent living in an ideal world, however rather
    than applying said SFINAE to the pointer you could do a similar SFINAE
    constraint with the function and provide various overloads and get the
    same effect.

    regards
    Andy Little
     
    kwikius, Jan 3, 2008
    #4
  5. kwikius Guest

    On 3 Jan, 14:17, kwikius <> wrote:



    >       typename quanta::where_<
    >          std::tr1::is_base_of<T,Derived>,
    >          void*
    >       >::type* =0


    ...Oops try changing quanta::where to enable_if ;-)

    regards
    Andy Little
     
    kwikius, Jan 3, 2008
    #5
  6. Salt_Peter Guest

    On Jan 3, 7:11 am, wrote:
    > I've used Boost for this example; in fact we have our own pointer
    > class, for historic reasons.
    >
    > #include "boost\shared_ptr.hpp"
    >
    > // A heirarchy of classes
    > class G1 {};
    > class G2: public G1 {};
    >
    > // A method which takes a shared pointer to the base class
    > void f(boost::shared_ptr<G1>) {};
    >
    > // A method which takes a shared pointer to some other class
    > void f(boost::shared_ptr<int>) {};
    >
    > void main()
    > {
    > // Call a method with a shared pointer to a derived class
    > f(boost::shared_ptr<G2>());
    >
    > }
    >
    > This fails, because the compiler is unable to decide which of the two
    > methods is meant. Of course, to a human, it's pretty obvious which
    > one is meant, but there doesn't seem to be enough information at the
    > time for the compiler to decide. In practice I have several hundred
    > functions, and 50 or so classes, to get confused among, so I don't
    > really want to take the obvious route [declare an
    > f(boost::shared_ptr<G2>) ]. Is there anything I can do to the pointer
    > class, or even to the class inheritance, that'll help the compiler
    > out?
    >
    > Thx


    How about templates:

    #include <iostream>
    #include "boost/shared_ptr.hpp"

    class G1
    {
    public:
    ~G1() { std::cout << "~G1()\n"; }
    };

    class G2: public G1
    {
    public:
    ~G2() { std::cout << "~G2()\n"; }
    };

    template< typename T >
    void f(boost::shared_ptr< T > bsp)
    {
    std::cout << "void f(boost::shared_ptr< T >&)\n";
    }

    template<>
    void f(boost::shared_ptr<G1> bsp)
    {
    std::cout << "void f(boost::shared_ptr<G1>&)\n";
    }

    template<>
    void f(boost::shared_ptr<int> bsp)
    {
    std::cout << "void f(boost::shared_ptr<int>&)\n";
    }

    int main()
    {
    f(boost::shared_ptr<G1>(new G2));
    }

    /*
    void f(boost::shared_ptr<G1>&)
    ~G2()
    ~G1() // even though that dtor isn't virtual!
    */
     
    Salt_Peter, Jan 3, 2008
    #6
  7. Guest

    On Jan 3, 4:27 pm, Salt_Peter <> wrote:
    <snip>
    > int main()
    > {
    > f(boost::shared_ptr<G1>(new G2));
    > }

    ^^^^^^^^^^^^^^^^^^^^^
    That's the critical bit. (or at least, if you are in the same font as
    me :) ) If the pointer passed to f *is* a shared_ptr<G1> then there's
    no confusion. It's only when it's some other type that the compiler
    goes hunting for a match - and finds two.

    --
    Old Faithful
     
    , Jan 3, 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. Pavol Droba
    Replies:
    0
    Views:
    325
    Pavol Droba
    Sep 27, 2004
  2. MotoK
    Replies:
    59
    Views:
    1,821
    Keith Thompson
    Sep 15, 2006
  3. n2xssvv g02gfr12930

    Smart pointers and member function pointers

    n2xssvv g02gfr12930, Nov 26, 2005, in forum: C++
    Replies:
    3
    Views:
    472
    n2xssvv g02gfr12930
    Nov 27, 2005
  4. cerr

    pointers, pointers, pointers...

    cerr, Apr 7, 2011, in forum: C Programming
    Replies:
    12
    Views:
    682
  5. Vladimir Menshakov
    Replies:
    1
    Views:
    364
Loading...

Share This Page