Как переслать объявить boost :: ptree :: iterator - PullRequest
4 голосов
/ 12 мая 2011

Я бы хотел использовать boost ptree в моем проекте, но так как ptree.hpp требует включения еще около 1000 заголовочных файлов, это значительно увеличивает время компиляции (например, с 1 до 7 с) и, поскольку это необходимо в более чем 20 различных файлах cpp это недопустимо (предварительно скомпилированные заголовки не сильно улучшают ситуацию). Так что я думаю об инкапсуляции 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, используя мои собственные функции-члены, но, как я понимаю из Как переслать объявление внутреннего класса? это вообще невозможно. Какие-нибудь изящные способы реализации итератора в этом классе?

Ответы [ 3 ]

4 голосов
/ 12 мая 2011

Ваша проблема - хороший кандидат для Pimpl идиома , он же брандмауэр компилятора , он же Handle-Body . Смотрите также эту статью . Решение, которое вы предлагаете, очень похоже на эту идиому.

Чтобы скрыть итератор ptree от своих клиентов, ознакомьтесь с техникой any_iterator, представленной в этой статье .

Вы можете найти реализации any_iterator здесь и здесь .

3 голосов
/ 12 мая 2011

У меня нет хорошего ответа на ваш настоящий вопрос, но предварительно скомпилированные заголовки должны быть значительным улучшением в этом случае.Вы уверены, что он действительно использовался, а заголовки не читались из каждого модуля компиляции?Это может быть немного сложно настроить оптимально.(то есть, избегайте «автоматической» опции)

0 голосов
/ 12 мая 2011

Спасибо за ваши ответы.Что касается предварительно скомпилированных заголовков, я проверил, что они действительно используются (g++ -H показывает около 1460 заголовочных файлов первоначально, и только около 30 при использовании предварительно скомпилированных заголовков) и время компиляции сократилось с 7 с до 5,5 с, что по-прежнему плохо по сравнению с1 при использовании вышеуказанного инкапсулированного класса.

Теперь, когда я попытался использовать 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;
   ...
};
...