худшее, что может случиться, если я не подчиняюсь догме о хранителях без сохранения состояния? - PullRequest
5 голосов
/ 06 ноября 2010

Мне нужно создать собственный распределитель для std :: objects (особенно и первоначально для std :: vector), но в конечном итоге он может использовать другие

Причина, по которой мне нужно создать собственный распределитель, заключается в том, чтоМне нужно отслеживать выделенные (куча и стек) ресурсы по отдельным компонентам приложения (, это неотъемлемая особенность приложения ).Мне понадобится специальный распределитель для мониторинга кучи ресурсов, поэтому очень важно, чтобы я мог передать конструктору std :: vector что-то вроде

trackerId idToTrackUsage;
myAlloca<int> allocator(idToTrackUsage);
vector<int> Foo( allocator );

Однако, прочитав немногоЯ обнаружил эту маленькую бомбу о стандарте STL / C ++ (см. Ссылки), который говорит, что все экземпляры распределителя данного типа должны быть эквивалентными (то есть == должен возвращать true для любых двух экземпляров) и большинство терминалов;любой распределитель должен иметь возможность освобождать память, выделенную любым другим экземпляром (то есть, не имея возможности узнать, каким может быть этот другой экземпляр).Короче говоря, у распределителей не может быть состояния.

Так что я пытаюсь найти лучший способ обойти это.Любые умные идеи?Я действительно ДЕЙСТВИТЕЛЬНО не хочу иметь собственную версию std :: vector.

РЕДАКТИРОВАТЬ: я читал о распределителях для c ++ 0x на http://www2.research.att.com/~bs/C++0xFAQ.html#scoped-allocator, но я не могЯ не очень понимаю, как это относится к моей проблеме.Если кто-то думает, что c ++ 0x облегчает эту проблему, пожалуйста, прокомментируйте

Список литературы:

Статья Allocator C ++ в Википедии

Некоторые случайные дальнейшиечтение предоставлено Google

Ответы [ 4 ]

5 голосов
/ 06 ноября 2010

Помимо очевидного ответа («если вы нарушите какое-либо требование, это неопределенное поведение, спокойной ночи и спасибо за игру»), я думаю, что худшее , которое может произойти, это то, что vectorреализация может опираться на требование, что «все экземпляры класса распределителя взаимозаменяемы» очевидным образом:

vector(const Allocator &youralloc = Allocator()) {
    const Allocator hawhaw;
    // use hawhaw and ignore youralloc. 
    // They're interchangeable, remember?
}

Глядя на источник, векторная реализация GCC (которая, я думаю, в конечном итоге основана на оригинальном STL SGIреализация) хранит копию объекта распределителя, переданного в этот конструктор, поэтому есть некоторая надежда, что этого не произойдет.

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

Если вам действительно повезет, есть некоторая документация для вашей реализации контейнера, в которой говорится о распределителях.

3 голосов
/ 06 ноября 2010

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

1 голос
/ 21 декабря 2011

Чтобы ответить на ваши изменения: да, в C ++ 0x или C ++ 11 распределители могут иметь состояние.

1 голос
/ 06 ноября 2010

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

...