[odb-users] std::set<odb::lazy_shared_ptr<foo>> fails

Miguel Revilla Rodríguez yo at miguelrevilla.com
Sun Aug 19 11:53:34 EDT 2012

Everything works perfectly now (including the subject in the other
mail). Thanks for you patience with such a noob :)


2012/8/19 Miguel Revilla Rodríguez <yo at miguelrevilla.com>:
> Hi,
> I see. Will try it right now. Sorry for not including the compilator
> messages. Will inform here if this works.
> Miguel
> 2012/8/19 Boris Kolpackov <boris at codesynthesis.com>:
>> Hi Miguel,
>> Miguel Revilla Rodríguez <yo at miguelrevilla.com> writes:
>>> I'm trying to declare an object with a
>>> std::set<odb::lazy_shared_ptr<foo>> member, and while the odb compiler
>>> works nicely on it and doesn't complain, later the generated code
>>> (object-odb.cpp) fails to compile with G++ 4.7.1 with options -O2
>>> -std=c++11.
>> When reporting that something fails to compile, it is always a good
>> idea to include the diagnostics from the compiler. Without it we can
>> only guess what could have gone wrong.
>>> If I change std::set with std::vector, then everything is fine, but
>>> I'd prefer to use a set rather than a vector in this case.
>> My guess is that the compiler complains there is no operator< defined
>> for odb::lazy_shared_ptr. The reason for this is that it is tricky to
>> come up with a universally-acceptable semantics. For example:
>> 1. How do we compare a transient object to a persistent one? Do
>>    we use the underlying pointers and if so what about unloaded
>>    pointers? Do we use object ids?
>> 2. When comparing unloaded persistent objects, do we take into
>>    account the database?
>> However, if you have some application-specific knowledge that
>> allows you to provide a sensible less-than comparison, then you
>> can easily add it as a second template argument to std::set.
>> For example, if you know that all the objects in your set will
>> be non-NULL and will have valid object ids (i.e., no object with
>> yet unassigned auto id will ever be added to the set), and they
>> will also be from the same database, then you can define an id-
>> based comparison:
>> template <typename T>
>> struct object_id_comparator
>> {
>>   bool operator (const odb::lazy_shared_ptr<T>& x,
>>                  const odb::lazy_shared_ptr<T>& y) const
>>   {
>>     return x.object_id<T> () < y.object_id<T> ();
>>   }
>> };
>> Then, in your persistent class, you can have:
>> std::set<odb::lazy_shared_ptr<foo>, object_id_comparator<foo>> foo_;
>> Boris

More information about the odb-users mailing list