如何转发声明 boost::ptree::iterator

发布于 2024-11-07 07:32:58 字数 1343 浏览 0 评论 0 原文

我想在我的项目中使用 boost ptree,但是由于 ptree.hpp 导致包含另外 1000 个头文件,这大大增加了编译时间(例如从 1 秒到 7 秒),并且由于 20 多个不同的 cpp 文件需要它,所以这不是可以接受(预编译头并没有太大改善)。所以我正在考虑将 boost ptree 封装在我自己的类中,例如

// 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;

};

但是,我无法以一种很好的方式实现迭代器。理想情况下,我希望有一个 boost::property_tree::ptree::iterator 作为私有成员变量,然后可以使用我自己的成员函数在 m_tree 上迭代,但是据我了解 如何转发声明内部类? 这通常是不可能的。在此类中实现迭代器有什么优雅的方法吗?

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 generally not possible. Any elegant ways of implementing an iterator within this class?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

顾北清歌寒 2024-11-14 07:32:58

您的问题很适合 Pimpl idiom,又名编译器防火墙,又名Handle-Body。另请参阅这篇文章。您提出的解决方案与该习惯用法非常相似。

要向客户端隐藏 ptree 的迭代器,请查看 any_iterator 技术。 html" rel="nofollow">这篇文章

您可以在此处此处

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.

套路撩心 2024-11-14 07:32:58

对于您的实际问题,我没有一个好的答案,但在这种情况下,预编译标头应该是一个重大改进。您确定它实际上正在被使用并且标头尚未从每个编译单元中读取吗?最佳设置可能有点棘手。 (即避免“自动”选项)

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)

小耗子 2024-11-14 07:32:58

感谢您的回答。关于预编译头,我检查了它们确实被使用了(g++ -H 最初显示了大约 1460 个头文件,使用预编译头时只有大约 30 个),编译时间从 7 秒减少到 5.5 秒,与使用上面的封装类时大约1s相比仍然不好。

现在,当我尝试使用 any_iterator (现在似乎也是 boost 的一部分)时,我意识到它还添加了数百个其他头文件,但简单地包含它们并没有增加太多编译时间。因此,我对 ptree 标头进行了相同的尝试,并包含 ptree.hpp 而不是 ptree_fwd.hpp,这增加了一点编译时间(从 1.1 秒到 1.8 秒) 。那么似乎只有在实例化 ptree 模板时才会出现严重的编译时间损失?这也可以解释为什么预编译头没有那么大的帮助?由于我很懒,而且由于我的主要问题是编译时间,我可能会坚持这样的做法:

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

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

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;
   ...
};
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文