2013-03-13 68 views
0

这个问题更适合Boost论坛吗?下面引用了完整的代码,我不认为我错误地尝试将auto_ptr序列化示例转换为unique_ptr示例,与此网站上的其他unique_ptr示例相比较。因此,为什么我会在Boost库中深处收到编译错误?我之前在标准容器上使用过Boost序列化,没有任何问题,尽管这是一个自定义适配器,但如果编译了类似的示例,为什么不呢?serialize不是std :: unique_ptr的成员

我引用http://www.boost.org/doc/libs/1_51_0/libs/serialization/example/demo_auto_ptr.cpp试图使用自定义适配器序列化我的二叉树。以下是表示sscce的代码转储。

// disables conversion from 'std::streamsize' to 'size_t', possible loss of data 
#pragma warning(disable:4244) 

#ifndef BINARY_SEARCH_TREE_H_ 
#define BINARY_SEARCH_TREE_H_ 

#include<functional> 

#include<memory> 
#include<fstream> 
#include<boost/archive/binary_oarchive.hpp> 
#include<boost/archive/binary_iarchive.hpp> 

#define BST_FILE_NAME "tree.dat" // default filename used to save and load 

namespace boost { 

    namespace serialization { 

     template <class Archive, class T> 
     inline void save 
      (Archive &archive, 
      const std::unique_ptr<T> &subtree, 
      const unsigned int file_version) 
     { 
      // only the raw pointer has to be saved 
      const T *const subtree_x = subtree.get(); 

      archive << subtree_x; 
     } 

     template <class Archive, class T> 
     inline void load 
      (Archive &archive, 
      const std::unique_ptr<T> &subtree, 
      const unsigned int file_version) 
     { 

      T *p_subtree; 

      archive >> p_subtree; 

      #if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1) 
       subtree.release(); 
       subtree = std::unique_ptr<T>(p_subtree); 
      #else 
       subtree.reset(p_subtree); 
      #endif 
     } 

     template <class Archive, class T> 
     inline void serialize 
      (Archive &archive, 
      const std::unique_ptr<T> &subtree, 
      const unsigned int file_version) 
     { 
      boost::serialization::split_free(archive, subtree, file_version); 
     } 

    } // namespace serialization 
} // namespace boost 


template <class T = int> 
class BinarySearchTree{ 

    class BinarySearchTreeNode{ 
    public: 

     std::unique_ptr<BinarySearchTreeNode> node_factory(const T &new_key, const T &new_index){ 
      return std::unique_ptr<BinarySearchTreeNode>(new BinarySearchTreeNode(new_key, new_index)); } 

     BinarySearchTreeNode(BinarySearchTreeNode &&other) : key(other.key), index(other.index), left(std::move(other.left)), 
      right(std::move(other.right)) {key = index = left = right = nullptr; } 

     BinarySearchTreeNode &operator=(BinarySearchTreeNode &&rhs) { if(this != rhs) { key = rhs.key; index = rhs.index; 
      left = std::move(rhs.left); right = std::move(rhs.right); 
      rhs.key = rhs.index = rhs.left = rhs.right = nullptr;} return *this;} 

     ~BinarySearchTreeNode() {} // Note to self; don't hide the destructor 

     friend class BinarySearchTree; 

    private: 

     friend class boost::serialization::access; 
     template<class Archive> 
     void serialize(Archive &archive, const unsigned int /* file_version */){ 
      archive & key; 
      archive & index; 
      archive & left; 
      archive & right; 
     } 

     T key; 
     long index; 

     std::unique_ptr<BinarySearchTreeNode> left; 
     std::unique_ptr<BinarySearchTreeNode> right; 

     BinarySearchTreeNode() {} 
     BinarySearchTreeNode(const T &new_key, const T &new_index) :key(new_key), index(new_index), 
            left(nullptr), right(nullptr) {} 

    }; 

    std::unique_ptr<BinarySearchTreeNode> root; 

    std::list<T> tree_keys; 
    std::list<long> tree_indicies; 



    friend class boost::serialization::access; 
    template <class Archive> 
    void serialize(Archive &archive, const unsigned int version){ 
     archive & root; 
    } 



    BinarySearchTree(const BinarySearchTree &other){} 
    BinarySearchTree &operator=(const BinarySearchTree &rhs){} 

    std::unique_ptr<BinarySearchTreeNode> insert(const T &new_key, const T &new_index, 
       std::unique_ptr<BinarySearchTreeNode> &tree){ 
     if(tree == nullptr){ 
      return root->node_factory(new_key, new_index); 
     }else if(std::less<T>() (new_key, tree->key)){ // Left insertion 
      tree->left = insert(new_key, new_index, tree->left); 
      return std::move(tree); 
     }else { // Right insertion 
      tree->right = insert(new_key, new_index, tree->right); 
      return std::move(tree); 
     } 
    } 

public: 
    BinarySearchTree() : root(nullptr) {} 
    BinarySearchTree(BinarySearchTree &&other) : root(std::move(other.root)) { other.root = nullptr; } 
    BinarySearchTree &operator=(BinarySearchTree &&rhs) { if(this != rhs) { root = std::move(rhs.root); 
     rhs.root = nullptr} return *this; } 
    bool insert_into_tree(const T &new_key, const T &new_index){ 
     if(new_key == NULL){ 
      return false; 
     } 
     root = std::move(insert(new_key, new_index, root)); 
     return true; 
    } 


    void save(const BinarySearchTree &tree) 
    { 
     // create and open a binary archive for output 
     std::ofstream writer(BST_FILE_NAME, std::ofstream::out | std::ofstream::binary); 

     if(writer){ 
      boost::archive::binary_oarchive serial_writer(writer); 
      //set_flags(0, true); 
      // write class instance to archive 
      serial_writer << tree; 
      // archive and stream closed when destructors are called 

     }else if(writer.fail()){ 
      writer.clear(); 
     } 
    } 

    void load(BinarySearchTree &tree) 
    { 
     // create and open a binary archive for output 
     std::ifstream reader(BST_FILE_NAME, std::ifstream::in | std::ifstream::binary); 

     if(reader){ 
      boost::archive::binary_iarchive serial_reader(reader); 
      // read class state from archive 
      serial_reader >> tree; 
      // archive and stream closed when destructors are called 

     }else if(reader.fail()){ 
      reader.clear(); 
     } 
    } 
    ~BinarySearchTree() {} 
}; 

#endif 

上述代码与树成员函数的任何用法一样编译。选择调用保存后,即出现编译器错误时。下面是主要的:

#include<cstdlib> 

#include "physical_view.h" 

using namespace std; 

int main(int argc, char *argv[]){ 


    BinarySearchTree<> tree; 

    tree.insert_into_tree(10, 5); 
    tree.insert_into_tree(5, 15); 
    tree.insert_into_tree(15, 10); <--------- All is wonderful to here! 

    tree.save(tree); <---------- Compiler unhappy here! 

    return EXIT_SUCCESS; 
} 

怎么样编译器错误:

Error 1 error C2039: 'serialize' : is not a member of 'std::unique_ptr<_Ty>' c:\boost_12\include\boost-1_53_1\boost\serialization\access.hpp 118 

我谢谢你帮我解决这个编译器错误。

+0

能否显示*确切*真实的代码,看起来你有一堆的语法错误。 – 2013-03-13 20:40:07

+0

尤其是你添加到'boost :: serialization'中的附加函数,特别是序列化函数,因为我怀疑这是你的错误所在。 – 2013-03-13 20:40:53

+0

代码对于转储来说太长,但我可以这样说,代码编译100%直到我准备好执行boost :: archive :: text_oarchive(某些流),然后出现错误。如果你仍然想看到所有的代码,请告诉我。 – user633658 2013-03-13 21:46:51

回答

1

这是你的序列化和加载函数的签名是不正确的。对于这两个参数,std::unique_ptr<T>参数都必须是非常量。由于它不能推导出类型(由于常量),它只是忽略了过载并且根本找不到它。

+0

美丽地模糊,并很好地解释。问题解决了。我没有注意到,我是(不正确地)把常量放在加载函数的第二个参数上,只要我从序列化中删除了常量,它仍然编译,但我已经删除了这两个参数。 – user633658 2013-03-15 15:51:11

相关问题