简体   繁体   中英

Move constructor for boost::property_tree::ptree

I use boost::property_tree::ptree quite a bit, but I've found that I create, pass around, and then save copies too many times. With big ptree objects this is expensive.

Boost provides a swap function, but no move constructor. Why would they do that?

My current solution is to extend ptree and make one myself:

class MyPtree : public boost::property_tree::ptree
{
  MyPtree(MyPtree&& other)
  {
    swap(other);
  }

  ... plus adding the other constructors and operators
};

Is this the best solution or am I missing something?

I think your solution is pretty decent. Note that it will never affect internal tree operations, as the tree will see its children as ptree , not MyPtree .

Slightly better is to propose the new feature and suggest it to de library devs.


Related is Is there a convenient way to erase a node from a property tree, preserving its child nodes? .

If you want to dig deeper, you'll find that Property Tree builds on Boost MultiIndex which, for various reasons, doesn't seemless allow moving from values: Move element from boost multi_index array

You could add a splice() operation building on the list-ness of the various indexes used:

For now, ptree could add a splice operation, which would naturally wrap multi_index's list operations : I just made a draft implementation sehe - Sep 23 '17 at 9:48

Stewart, I've seen the ptree destructor and it seems that it's not virtual. It means the base destructor (ptree) will not be invoked if MyPtree is used polymorphically. Maybe you should consider to use composition instead of inheritance. See this answer 在此输入图像描述

This might be a sketch:

class MyPtree
{
   boost::property_tree::ptree m_tree;

   MyPtree(MyPtree&& other)
   {
      m_tree.swap(other.m_tree);
   }

  ... plus adding the other constructors and operators
};

use composition instead inheritance

class MyPtree
{
public:
  MyPtree():{m_tree_ptr = new boost::property_tree::ptree();
  MyPtree(MyPtree&& other){m_tree_ptr = other.m_tree_ptr; other.m_tree_ptr = nullptr;}
  ~MyPtree(){if (m_tree_ptr != nullptr) delete m_tree_ptr;}
  // copy conctructor and assign operator

private:
 boost::property_tree::ptree* m_tree_ptr;
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM