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

Miguel Revilla Rodríguez yo at miguelrevilla.com
Sun Aug 19 10:31:12 EDT 2012


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