[odb-users] Support c++11

Boris Kolpackov boris at codesynthesis.com
Fri Jun 1 11:51:27 EDT 2012

Hi Andrey,

I am glad you found an answer to your question. However, here
are some efficiency/correctness suggestions:

Andrey Devyatka <an9bit at gmail.com> writes:

> auto res = db->query<DBO>(query);
> for( auto at : res) {

Here you are making a copy of an object as you are iterating
because 'at' is a value. If the object is not polymorphic,
then this will be just less efficient. Howevere, if the object
is polymorphic, then the copy could be "sliced". A better way
is to make 'at' a reference:

auto res = db->query<DBO> (query);
for (auto& at : res) {

Also, we can move the call to query() inside the for-loop:

for (auto& at : db->query<DBO> (query)) {

> for(DBO at : res) {
>     list.push_back(std::shared_ptr<DBO>(new DBO(at)));
> }

Here you are making two copies, the first as dicussed above, and
the second explicitly. If you want a pointer to the object, then
it is more efficient to use the load() function, wich will allocate,
initialize, and return the object without making any copies. In this
case, however, we cannot use the range-based for-loop since we need
access to the iterator:

for (auto i = res.begin (); i != res.end (); ++i)
  list.push_back (std::shared_ptr<DBO> (i.load ()));

If DBO's canonical object pointer is std::shared_ptr, then this
code can be simplified further since load() will return the pointer
as shared_ptr:

for (auto i = res.begin (); i != res.end (); ++i)
  list.push_back (i.load ());

More information about the odb-users mailing list