Boost logo

Boost :

From: vicente.botet (vicente.botet_at_[hidden])
Date: 2008-01-28 14:48:07

> > >
> > > * The resulting equality semantics might not coincide with that of
> > > the underlying T; the possibility of this hapenning and making a
> > > real difference is probably small, though.
> > Please could you give us un example on which the first problem is
> > present?
> The situation would be one in which the equivalence criteria
> used by the flyweight factory would not be the same as
> induced by T::operator==, that is, if two flyweight objects fw1, fw2
> are such that fw1!=fw2 yet fw1.get()==fw2.get() (the converse, i.e.
> fw1==fw2 and fw1.get()!=fw2.get(), cannot happen). The following is
> an admittedly artificial example:
> class istring:public std::string
> {
> public:
> istring(const char* p):std::string(p){}
> friend inline bool operator==(const istring& x,const istring& y)
> {
> return stricmp(x.c_str(),y.c_str())==0; // case insensitive
> }
> };
> typedef flyweight<istring,set_factory<> > fw_t;
> int main()
> {
> fw_t fw1("hello"),fw2("HELLO");
> assert(fw1!=fw2);
> assert(fw1.get()==fw2.get());
> }
> Upon seeing this example, I'm growing more suspicuous that
> maybe I'm being too precautious: situations like this are
> extremely unlikely. Maybe the design is good as it is, and
> equality of flyweights should just be based on &-equality.

If I understand the class istring will work well with a default
hashed_factory because the default factory use the == operator to state when
the value can be shared. This will not be the case if another Predicate is
used as parameter to the hashed_factory.

The problem with the set_factory for this class is that istring("hello") ==
istring(HELLO) and istring("hello") < istring(HELLO).

You are right this is a quite extrange. So if a value type T satisfy
  for all T t1, t2 / t1==t2 => !((t1<t2) || (t2<t1))

then we can define the flyweight equality as follows: two flyweight objects
can be considered equal if they share their value but if this is not
satisfied the flyweight equality must resort to the underlying values.

The problem is that this can not be cheched, so why not rely on some traits
class and let the user state what he/she prefers.

// by default considered equal if they share their value
template <typename T>
struct flyweight_equals_if_shared_value : boost::mpl::true_{};

// resort to the underlying values.
template <>
struct flyweight_equals_if_shared_value<istring> : boost::mpl::false_{};

Can this be used to solve the equality semantic problems?


Vicente Juan Botet Escriba

Boost list run by bdawes at, gregod at, cpdaniel at, john at