[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 :)

Miguel

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