[odb-users] Find the bug under odb::lazy_shared_ptr source code

陈焕鑫 202121046942 at mail.scut.edu.cn
Sun May 21 11:48:27 EDT 2023


I'm using the odb::lazy_shared_ptr pointer to implement a one-to-one relationship, as shown below

#pragmadbobject
classemployee
{
    ...


    #pragmadbidauto
    unsignedlongid;


    #pragmadbnot_null
    odb::lazy_shared_ptr<Article> positions;
};
Then I try to load the positions under the driver.cxx file




unsignedlongsearch_id = 52;
std::shared_ptr<employee> emp(db->load<employee>(search_id));
emp->positions.load(); // delay load

It has an error, and the error message reported is as follows





/usr/include/odb/lazy-ptr.ixx:1153:10: error: no match for ‘operator=’ (operand types are ‘std::shared_ptr<Article>’ and ‘odb::object_traits<Article>::pointer_type’ {aka ‘Article*’})
 1153 |       p_ = i_.template load<T> (true); // Reset id.
      |       ~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /usr/include/c++/10/memory:84,
                 from driver.cxx:4:
/usr/include/c++/10/bits/shared_ptr.h:358:19: note: candidate: ‘std::shared_ptr<_Tp>& std::shared_ptr<_Tp>::operator=(const std::shared_ptr<_Tp>&) [with _Tp = Article]’
  358 |       shared_ptr& operator=(const shared_ptr&) noexcept = default;
      |                   ^~~~~~~~
/usr/include/c++/10/bits/shared_ptr.h:358:29: note:   no known conversion for argument 1 from ‘odb::object_traits<Article>::pointer_type’ {aka ‘Article*’} to ‘const std::shared_ptr<Article>&’
  358 |       shared_ptr& operator=(const shared_ptr&) noexcept = default;
      |                             ^~~~~~~~~~~~~~~~~
/usr/include/c++/10/bits/shared_ptr.h:362:2: note: candidate: ‘template<class _Yp> std::shared_ptr<_Tp>::_Assignable<const std::shared_ptr<_Yp>&> std::shared_ptr<_Tp>::operator=(const std::shared_ptr<_Yp>&) [with _Yp = _Yp; _Tp = Article]’
  362 |  operator=(const shared_ptr<_Yp>& __r) noexcept
      |  ^~~~~~~~




================================== 

It seems that you  cannot assign a rawpointer directly to a shared pointer

The problem is with line 1153 of /usr/include/odb/lazy-tr.ixx

  template <classT>
  inlinestd::shared_ptr<T> lazy_shared_ptr<T>::
  load () const
  {
    if (!p_ && i_)
      p_ = i_.template load<T> (true); // Reset id.



    returnp_;
  }
The problem was solved when I changed the code to the following

  template <classT>
  inlinestd::shared_ptr<T> lazy_shared_ptr<T>::
  load () const
  {
    if (!p_ && i_)
      //p_ = i_.template load<T> (true); // Reset id.
      p_.reset(i_.templateload<T> (true)); // Reset id.


    returnp_;
  }
you  can use method reset() to transfer a rawpointer directly to a shared pointer.


More information about the odb-users mailing list