开发者

How to forward declare boost::ptree::iterator

开发者 https://www.devze.com 2023-03-05 01:20 出处:网络
I\'d like to use boost ptree in my project but since ptree.hpp causes about another 1000 header files to be included this increases compile times drastically (e.g. from 1s to 7s) and as it\'s needed i

I'd like to use boost ptree in my project but since ptree.hpp causes about another 1000 header files to be included this increases compile times drastically (e.g. from 1s to 7s) and as it's needed in over 20 different cpp files this is not acceptable (pre-compiled headers don't improve things much). So I'm thinking of encapsulating the boost ptree in my own class, something like

// myptree.h
#include <boost/property_tree/ptree_fwd.hpp>

class myptree {
   private:
      boost::property_tree::ptree *m_tree;

   public:
      ...
     // adding new (single value) members to the the tree
     void put(const std::string&, double);
     void put(const std::string&, int);
     void put(const std::string&, const std::string&);

     // returning (single value) members of the tree
     double get_double(const std::string&) const;
     int get_int(const std::string&) const;
     std::string get_str(const std::string&) const;

     // working with subtrees
     void push_back(const std::string&, const myptree&);
     myptree get_child(const std::string&) const;

     // import/export
     void read_from_json(const std::string&);
     void write_to_json(const std::string&) const;

};

However, I'm failing to implement an iterator in a nice way. Ideally I'd like to have a boost::property_tree::ptree::iterator as a private member variable which then could be iterated over m_tree using my own member functions but as I understand from How do I forward declare an inner class? this is general开发者_StackOverflow中文版ly not possible. Any elegant ways of implementing an iterator within this class?


Your problem is a good candidate for the Pimpl idiom, aka compiler firewall, aka Handle-Body. See also this article. The solution you're proposing closely resembles that idiom.

To hide ptree's iterator from your clients, check out the any_iterator technique presented in this article.

You can find implementations of any_iterator here and here.


I don't have a good answer to your actual question, but pre-compiled headers should be a significant improvement in that case. Are you sure it was actually being used and the headers were not still being read from each compilation unit? It can be a little bit tricky to set up optimally. (i.e., avoid the "automatic" option)


Thanks for your answers. Regarding precompiled headers, I checked that they're actually used (g++ -H shows about 1460 header files originally, and only about 30 when using precompiled headers) and compile time reduced from 7s down to 5.5s which is still not good compared to about 1s when using the above encapsulated class.

Now, when I tried using any_iterator (which seems to be part of boost now as well) I realised it also added some hundreds of other header files but simply including them didn't increase compile times much. So I tried the same with the ptree header and included ptree.hpp instead of ptree_fwd.hpp and that increased compile time by just a bit (from 1.1s to 1.8s). So it seems the heavy compile time penalty comes only when the ptree templates are instantiated? That might also explain why pre-compiled headers didn't help that much? Being lazy and since my main problem was compilation time I might just stick to something like:

// myptree.h
#include <boost/property_tree/ptree.hpp>

class myptree {
   private:
      boost::property_tree::ptree           m_tree;
      boost::property_tree::ptree::iterator m_it;
   ...
};
0

精彩评论

暂无评论...
验证码 换一张
取 消