Le 7 oct. 2014 à 18:18, Joaquín Mª López Muñoz
El 07/10/2014 15:06, Akim Demaille escribió:
I have tried deriving from flyweight to add an operator->, but it fails horribly.
This is how the derivation would be done (I've tried with your code and it works, effectively eliminating the need to do .get()-> rather than -> ):
struct Exp:boost::flyweight
{ using super=boost::flyweight ; using super::super; using element_type=super::value_type::element_type; const element_type& operator*() const{return *(this->get());} const element_type* operator->()const{return &*(this->get());} };
That's about what I did, except that I felt free to use decltype.
bool operator==(const Exp& l, const Exp& r) { return *l == *r; }
bool operator!=(const Exp& l, const Exp& r) { return !(l == r); }
Actually I also had to solve this issue for == and !=, which seemed fishy, and I was afraid I would have to address a larger set of functions in the Real World Case.
I think this approach is OK: elements must be stored through some type of pointer because they're polymorphic, and, variants banned, std::shared_ptr<Base> seems a sensible choice.
Agreed.
An alternative would be to use some sort of cloning smart pointer to spare the reference count, but it's not clear to me this would be faster than shared_ptr:
* element exists: shared_ptr creation is slower than clone_ptr creation * element does not exist: shared_ptr creation and copy is probably faster than clone_ptr creation and cloning.
Yes, indeed.
So, if in doubt profile and determine what's best for you.
Yes, I'll bench the result. 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?