
Hi Emil ----- Mensaje original ----- De: Emil Dotchevski <emil@revergestudios.com> Fecha: Miércoles, Noviembre 14, 2007 8:36 pm Asunto: Re: [boost] Formal review request: Flyweight Para: boost@lists.boost.org [...]
struct name_tag1{}; typedef flyweight<std::string,tag<name_tag1> > str1_t;
struct name_tag2{}; typedef flyweight<std::string,tag<name_tag2> > str2_t;
The problem is that now str1_t and str2_t are distinct types in the type system, yet they are identical semantically. Suppose I have a function that takes a flyweight string like this:
void foo( flyweight<std::string> const & s );
Even if implicit conversions between different configurations of flyweight<std::string> exists, calling foo with str1_t or str2_t would create unwanted temporary objects. Besides, such conversions will create a default-configured flyweight<std::string>, which is not desirable. The only option I would have is to make foo a template which is unfortunate because it would increase physical coupling unnecessarily.
Compare this with the way users supply custom allocators to shared_ptr:
http://www.boost.org/libs/smart_ptr/shared_ptr.htm#allocator_constructo r
Two shared_ptr<T> objects that use different allocators, once initialized, are indistinguishable from each other because they are of the same type, shared_ptr<T>.
I would like flyweight<T> configuration to work similarly.
Your proposal is, as I see it, to some extent akin to a *local_flyweight* variant Tobias Schwinger and I were privately discussing some time ago: The shared_ptr allocator ctor accepts the *context* the shared_ptr object needs during its lifetime, namely the associated allocator and deleter. For flyweight, the context consists of the flyweight factory and some synchronization objects. So, the analog of shared_ptr allocator ctor in the realm of flyweight would be something like: template<typename T1,...,typename Tn> local_flyweight([const] T1&,...,[const] Tn&,context *); where context is an associated type containing all the static stuff, the factory and such. This can be done and would achieve a separation of "domains" without using different types, just as you demand (if I'm getting you right). This local_flyweight<> has other features apart from domain separation, like for instance the ability for the user to control the lifetime of the flyweight and the possibility of creating unlimited domains at run time (tag separation is a compile time artifact and as such the number of different domains one can create this way is fixed at programming time.) Why implementing this in a different class than flyweight<> itself? The reason is the value objects of local_flyweight<> (the elements stored at the flyweight factory, which contain the shared data as well as some bookkeeping info) must have a pointer to its context, whereas in the case of flyweight<> this context is associated to the type itself, thus saving us a pointer per value. Would this local_flyweight<> address your needs? If so, I plan to evolve the idea over time and either have it implemented for the review or else included in the future work section. Let me know what you think about it. Joaquín M López Muñoz Telefónica, Investigación y Desarrollo