C ++ ODB数据库映射器:无法在关系中使用std :: weak_ptr

时间:2018-08-02 11:45:50

标签: c++ c++11 odb

我正在尝试与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 --database sqlite --generate-query --generate-schema   -一次一次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尝试在某个地方从std::weak_ptr<Bar>创建Bar *,这显然是不可能的。它必须从std::shared_ptr<Bar>创建它。但是,ODB文档明确表示,在这种情况下,应该(实际上必须)使用std::weak_ptr

我在做什么错了?

1 个答案:

答案 0 :(得分:0)

好的,我想出了一个解决方案(不确定是否是最好的解决方案):

您可以强制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

相关问题