
Le 7 oct. 2014 à 20:41, Joaquin M Lopez Munoz <joaquin@tid.es> a écrit : Hi Joaquín,
A slightly smarter approach involves a cloning class that accepts a const Base& and does only clone on copy, thus avoiding dynamic memory allocation when the element already exists.
That's nice!
template<typename Base> bool operator==( const poly_flyweight<Base>& l,const poly_flyweight<Base>& r) { return static_cast<boost::flyweight<poly_holder<Base>>>(l)== static_cast<boost::flyweight<poly_holder<Base>>>(r); }
template<typename Base> bool operator!=( const poly_flyweight<Base>& l,const poly_flyweight<Base>& r) { return !(l==r); }
Yes, indeed, equality and hashing were uselessly deep in my example.
I've rewritten your test case to take advantage of this poly_flyweight thing, cleaning up some unnecessary hash and operator== overloads along the way and without resorting to the intermediate Exp_ type; see:
Thanks, I'll toy with it. Do you have any gut feeling about whether there should be only a single Exp-level hash-consing, or something with one flyweight per AST type (and conversions). I'm still considering both.
Is there anyway Flyweight could have supported the operator-> natively?
It seems that with some SFINAE under the hood, it would work, don't you think?
Yep, that would be possible, the only reason I didn't do it is to not clutter the interface. Also, some std classes such as (C++17) std::optional implement operator* differently, without the extra dereference required by smart pointer semantics.
You lost me here, I have no idea what special trick in std::optional would prevent Flyweight from completing its forwarding to such operators. I'll look for the proposal to try to understand the connection, thanks!