簡體   English   中英

C ++ ODB數據庫映射器:無法在關系中使用std :: weak_ptr

[英]C++ ODB database mapper: Unable to use std::weak_ptr in relationship

我正在嘗試與ODB建立一對多關系。 我基本上是想在https://www.codesynthesis.com/products/odb/doc/manual.xhtml#6.2.2中重新創建示例

我必須對關系的一側使用std::weak_ptr ,以避免循環所有權問題。 但是,我的非常簡單的示例代碼無法編譯,因為ODB在std :: weak_ptr上似乎不能很好地發揮作用。

在我的示例中,每個Bar都只有一個Foo ,而每個Foo都有多個Bar 這是我的代碼:

#include <odb/core.hxx>
#include <string>
#include <memory>
#include <vector>

// Forward
class Foo;

#pragma db object
class Bar {
public:
    // A Bar has exactly *one* Foo
    #pragma db not_null
    std::shared_ptr<Foo> cfg;

private:
    #pragma db id auto
    unsigned long id_;
    friend class odb::access;
};

#pragma db object
class Foo {
public:
    // A Foo has multiple Bars
    // Using std::weak_ptr here instead of std::shared_ptr to avoid circular
    // ownership
    #pragma db value_not_null inverse(cfg)
    std::vector<std::weak_ptr<Bar>> entries;

private:
    #pragma db id auto
    unsigned long id_;
    friend class odb::access;
};

int main() {}

我用以下方法生成數據庫代碼:

odb --std c ++ 11-數據庫sqlite-生成查詢-生成模式-一次一次main.hpp

我這樣編譯:

g ++ --std = c ++ 11 main.hpp main-odb.cxx

(我知道鏈接時會崩潰-我只是想使其編譯。)

我的編譯器(GCC 7)告訴我:

main-odb.cxx: In static member function ‘static void odb::access::object_traits_impl<Foo, (odb::database_id)1u>::entries_traits::init(odb::access::object_traits_impl<Foo, (odb::database_id)1u>::entries_traits::value_type&, const odb::access::object_traits_impl<Foo, (odb::database_id)1u>::entries_traits::data_image_type&, odb::database*)’:
main-odb.cxx:794:43: error: no matching function for call to ‘std::weak_ptr<Bar>::weak_ptr(odb::object_traits<Bar>::pointer_type)’
             obj_traits::object_type > (id));
                                           ^
In file included from /usr/include/c++/5/memory:82:0,
                 from main.hpp:3,
                 from main-odb.hxx:16,
                 from main-odb.cxx:7:
/usr/include/c++/5/bits/shared_ptr.h:492:2: note: candidate: template<class _Tp1, class> std::weak_ptr<_Tp>::weak_ptr(std::weak_ptr<_Tp1>&&)
  weak_ptr(weak_ptr<_Tp1>&& __r) noexcept
  ^
/usr/include/c++/5/bits/shared_ptr.h:492:2: note:   template argument deduction/substitution failed:
main-odb.cxx:794:43: note:   mismatched types ‘std::weak_ptr<_Tp>’ and ‘odb::object_traits<Bar>::pointer_type {aka Bar*}’
             obj_traits::object_type > (id));

我還跳過了另外三個候選人。 重要的部分:ODB嘗試在某個地方通過Bar *創建std::weak_ptr<Bar> ,這顯然是不可能的。 它必須從std::shared_ptr<Bar>創建它。 但是,ODB文檔明確表示,在這種情況下,應該(實際上必須)使用std::weak_ptr

我究竟做錯了什么?

好的,我想出了一個解決方案(不確定是否是最佳解決方案):

您可以強制ODB在所有地方使用std::shared_ptr<Bar>而不是Bar * 通過將您的班級定義為:

#pragma db object pointer(std::shared_ptr)
class Bar {
...

這樣,當創建std::weak_ptr<Bar> ,它是從有效的std::shared_ptr<Bar>創建的。 您還可以指定要在命名空間或全局范圍內使用的指針類型,請參見https://www.codesynthesis.com/products/odb/doc/manual.xhtml#3.3

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM