[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