Boost logo

Boost Users :

Subject: [Boost-users] Using shared_ptr with reference_wrapper
From: Kelvin Chung (kelvSYC_at_[hidden])
Date: 2012-01-19 15:15:39


I am currently in the middle of a wrapper conundrum. I currently have
the following:

template <class Key, class Container>
class ContainerWrapper {
        Container container;
public:
        typedef Key key_type;
protected:
        virtual const typename Container::key_type& mapKey(const key_type&) = 0;
};

The idea of ContainerWrapper is that I want to disguise one Key type as
another key type. But the following wrapper, intended to present a
container of Key pointers as a container of Keys, presents a dangling
reference problem:

template <class Key, class Container>
class HeapKeyWrapper : public ContainerWrapper<Key, Container> {
        // Container::key_type == boost::shared_ptr<Key>
public:
        typedef Key key_type;
protected:
        // Ignore the lack of boost::const_pointer_cast<Key>() below. The
dangling reference is from the fact
        // that shared_from_this() doesn't return a reference.
        const boost::shared_ptr<Key>& mapKey(const key_type& key) { return
key.shared_from_this(); }
};

If I try to fix this by having mapKey() return by value, then this
other wrapper breaks:

template <class Key, class Container>
class IdentityWrapper : public ContainerWrapper<Key, Container> {
public:
        typedef Key key_type;
protected:
        // Assume Key extends boost::enable_shared_from_this<Key>.
        // Returning by value would mean the returned value is a copy of key,
and not the original
        // so calling shared_from_this() from the mapped key would break, say
        const Key& mapKey(const key_type& key) { return key; }
};

I'm trying to fix the code so that both wrappers work (short of
refactoring the mapKey() functionality to a functor of some sort),
which leads me thinking about using boost::reference_wrapper in some
way. (The problem that I have is that I could have
IdentityWrapper::mapKey() return a reference_wrapper, but that violates
the mapKey() interface.)

This has also led me down to a related path - what if I changed my
backing container to use reference_wrapper instead of shared_ptr? It
seems to be that it is ill-advised: the container technically isn't
holding the object, and so the objects in the container could be
deallocated in the meantime, leaving me with containers full of
dangling references. I have valid uses of both HeapKeyWrapper and
IdentityWrapper elsewhere in my code, so what do you think should be
the right choice given this dangling reference problem currently
present in HeapKeyWrapper?


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