Сокращение раздувания кода STL путем упаковки контейнеров - PullRequest
2 голосов
/ 15 февраля 2011

У меня есть библиотека C ++ (с более чем 50 исходными файлами), которая использует много процедур STL с первичными контейнерами, являющимися списком и вектором. Это привело к огромному раздуванию кода, и я хотел бы уменьшить его, создав обертку над списком и вектором.

Ниже показана моя оболочка над std :: и упакованными экземплярами.

template<typename T>
class wlist
{
private:
    std::list<T> m_list;

public:

    // new iterator set.
    typedef typename std::list<T>::iterator iterator;
    typedef typename std::list<T>::const_iterator cIterator;
    typedef typename std::list<T>::reverse_iterator reverse_iterator;

    unsigned int size () { return m_list.size(); }
    bool empty () { return m_list.empty(); }
    void pop_back () { m_list.pop_back(); }
    void pop_front () { m_list.pop_front(); }
    void push_front (T& item) { m_list.push_front(item); }
    void push_back (T item) { m_list.push_back(item); }
    iterator insert(iterator position, T item) {m_list.insert(position,item);}
    bool delete_item (T& item);
    T back () { return (m_list.empty()) ? NULL : m_list.back();}
    T front () { return (m_list.empty()) ? NULL : m_list.front();}
    iterator erase(iterator item ) { return m_list.erase(item); }
    iterator begin() { return  m_list.begin(); }
    iterator end() { return m_list.end(); }
    reverse_iterator rbegin() { return  m_list.rbegin(); }
};

Файл A:

class label {

public:

int getPosition(void);
setPosition(int x);

private:

wlist<text*> _elementText; // used in place of list<text> _elementText;

}

Файл B:

class image {

private:

    void draw image() {
        wlist<label*>::iterator currentElement = _elementText.begin();
       ((label*)(*currentElement))->getPosition();    
        currentElement ++;
    }
}

Мое убеждение было в том, что, обернув контейнер STL, я смогу уменьшить раздувание кода, но уменьшение размера кода кажется незначительным, в то время как моим мотивом для обертывания STL было достижение сокращения кода примерно на 20%.

1) Предоставляя «обернутый» итератор, я в свою очередь встроил STL в свой клиентский код, тем самым сводя на нет все сохранение кода, которое я пытался сделать ???? 2) Я выбрал правильный метод профилирования ????

Размер до модификации:

$ size libWrap.so

text:  813115
data: 99436
bss:  132704
dec : 1045255
hex:  ff307     

Размер после модификации:

$ size libWrap.so

text:  806607
data: 98780
bss:  132704
dec : 1038091
hex:  fd70b

Ответы [ 3 ]

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

Во-первых, интерфейс, предлагаемый вашей оберткой, совершенно отвратителен. Есть причина, по которой существуют итераторы, и это потому, что ваша реализация не работает для типов без указателей. Возврат и взятие по значению вместо ссылки? Ужасный дизайн.

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

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

В-четвертых, даже идея раздувания кода довольно нелепа на подавляющем большинстве платформ. Я, конечно, не могу с умом понять, что вы работаете не на какой-то встроенной платформе с почти отсутствующей памятью (хотя я сомневаюсь, что вы бы использовали много списков на такой платформе), но практически на каждой системе размер самого кода по сравнению с этим не имеет смысла на другие активы, необходимые для выполнения программы.

Что вы можете сделать, это попробовать что-то вроде SCARY итераторов или частичных специализаций для T *.

1 голос
/ 05 мая 2011

Я пытаюсь представить, почему вы обеспокоены этим. Почему это проблема?

Я предполагаю, что у вас есть много (сотни?) Разных классов, и каждый генерирует копию шаблонных контейнеров.

Если это так и если это необходимо, то откиньтесь на спинку кресла и позвольте компилятору сделать вам утомительную работу.

Если в этом нет необходимости, то, вероятно, проблема в том, что все ваши разные классы не нужны. Есть проблема с дизайном вашего класса. У вас может быть много разных классов, которые отличаются незначительно. Если разница настолько мала, что дополнительный код, сгенерированный для обработки разницы, кажется непропорциональным, то другое поведение может быть лучше обработано кодом внутри одного класса.

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

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

Помещение шаблонного кода в файл .cpp обычно приводит к ошибкам компоновщика. Чтобы избежать этого, вам нужно явно объявить шаблоны, которые вы хотите, чтобы компилятор компилировал в файле cpp:

В конце файла .cpp вы пишете что-то вроде

template class wlist<double>;
template class wlist<int>;

и т.д.

Это указывает компилятору компилятору компилировать эти версии класса (и только эти версии). Это приводит к снижению гибкости вашей библиотеки - если вы вызовете wlist<complex>, вы получите ошибки компоновщика.

Смотрите здесь для получения дополнительной информации: http://www.parashift.com/c++-faq-lite/templates.html#faq-35.12

Я полагаю, что это обычно делается для сокращения времени компиляции - я полагаю, что это также уменьшит раздувание кода, но я никогда не использовал технику по этой причине и поэтому никогда не проверял размер моего исполняемого файла ....

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...