Boost logo

Boost Users :

Subject: Re: [Boost-users] Flyweight: wrapping shared_ptr
From: Akim Demaille (akim_at_[hidden])
Date: 2014-10-08 12:32:57


Le 8 oct. 2014 à 15:33, Joaquin M Lopez Munoz <joaquin_at_[hidden]> a écrit :

>> I expect the flyweight implementation to support inheritance, just
>> as
>>
>> std::shared_ptr<base> p = std::make_shared<derived>();
>
> This is alas not the case for flyweight<base>/flyweight<derived>. You
> can simulate something like that behavior in poly_flyweight:
>
> template<typename Derived>
> class poly_flyweight
> {
> ...
> operator flyweight<Base>()const;
> ...
> };
>
> but invoking this operator for a poly_flyweight<Derived> object x
> would imply creating a clone of x.get() (upcasted to const Base*) in
> poly_flyweight<Base> internal factory, which is a waste of space and
> brings you to the original situation where all objects are stored in
> the same factory.

I used something more agressive:

template <typename T>
class poly_flyweight
  : public boost::flyweight<poly_holder<T>>
{
public:
  using super = boost::flyweight<poly_holder<T>>;
  using super::super;

  /// Conversion to superclass.
  template <typename U>
  operator const poly_flyweight<U>&() const
  {
    const void* me = this;
    return *static_cast<const poly_flyweight<U>*>(me);
  }

  const T& operator*() const { return base(); }
  const T* operator->() const { return &base(); }

private:
  const T& base()const { return this->get(); }
};

of course I need to enable this conversion only when one
can convert from T to U.

However, while this adresses:

  NumFW a = num(1);
  Exp b = a;

it does not work for:

  Exp c(a);

even if I try to add a constructor to the poly_flyweight:

  template <typename U>
  explicit poly_flyweight(const poly_flyweight<U>& x)
    : poly_flyweight(static_cast<const poly_flyweight&>(x).base())
  {}

I have to make it explicit to avoid ambiguities, but then my
ctor is never ever called. I suspect that there is a perfect
forwarding constructor inside boost::flyweight that is preferred
by the compiler.

I have quite a headhack now, I gotta stop :) Again, thanks a lot
Joaquín.

(Actually it looks like what I did is not even portable: my
clang 3.5 is happy with it, but not Coliru's gcc
http://coliru.stacked-crooked.com/a/0cfe34a8ba934fea)


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