Здравствуйте Павел Кузнецов, Вы писали:
O>>разве модель памяти — то же самое, что и модель распределения? ПК>Нет, но контейнер интересует как раз нечто, что умеет выделять/освобождать память; откуда это нечто ее берет контейнеру не интересно, за исключением того, какие в ней положены ссылки и указатели.
Уточнение — выделение/освобождение интересует контейнер при добавлении/удалении элементов в контейнере, в остальное время его интересует только память (именно, какие в ней положены ссылки и указатели)
ПК>>>В своем rebind ты можешь выбирать <...> O>>Каким образом я могу выбирать? <...> ПК>Для выражения `sizeof(U) <= threshold'. Например, так (без частичной специализации, чтобы работало на VC++):
Это-то понятно, но при необходимости сделать более сложную систему, особенно при принятии решений времени выполнения, сложность подобных rebind, etc возрастает неимоверно. В данном случае ты соответствуешь Страуструпу — простые вещи расписаны, сложные оставлены в качестве упражнения.
Могу заверить, что в простых случаях я и сам могу разобраться См. также ниже.
[код поскипан]
ПК><...> А как ты предлагаешь делать это по-другому? Стандартизировать какой-либо частный подход типа фабрик распределителей (звучит-то как) или подобного предлагать не надо, т.к. в интерфейсе это ничего не меняет, а является реализацией.
Стоп-стоп, я пока ничего (почти) не предлагаю. Опять же, см.ниже
<...> ПК>Я бы сказал "интерфейс". Так, имхо, и должно быть: как мы уже договорились, распределитель не представляет собой саму память, а только способ работы с ней. Разве что, по мере накопления опыта, можно будет сформулировать семантику в случае, когда распределители имеют состояние.
Не будем спорить о терминах, хотя я и не совсем согласен.
O>>Всё это так, пока мы не разделим распределитель и память. splice между разной памятью — O(n), splice внутри одной памяти с любыми распределителями — O(1) ПК>Так и в настоящий момент никто не неволит связывать распределитель и память. Делай, как тебе нравится.
Я полагаю, что я всегда могу делать, как мне нравится (по-крайней мере в рамках стандарта). Другой вопрос, который собственно меня больше всего интересует, это идентификация потенциальных проблем и затыков в том, что предлагается стандартом. Поэтому я и затеял эту тему. Я хочу понять, что и, главное, почему было сделано при стандартизации библиотеки, на какие копромиссы пришлось пойти и ради чего. Например, как мы обсуждали с dupamid, в стандартном аллокаторе я никак не могу сконструировать объект другим конструктором (не копирования), поэтому ценность construct() резко падает. Дальше больше, поскольку конструировать становится проблематично, приходится откатываться на placement new, а это значит что ценность аллокатора остаётся лишь в аллокации.
Итак, имеем:
— конструировать объекты [в общем случае] нельзя
— память может быть только "совместимой" с обычной (за исключением возможно модификаторов типа far, но это не так важно в наше время, по крайней мере сходу мне не приходит в голову никакой реальной потребности)
— для использования требуется множество плясок (пусть эти пляски пишутся один раз, но ведь расширение тоже усложняется)
Остаётся только одно — распределение памяти. Не так уж и мало, но зачем тогда весь остальной огород?
Здравствуйте Павел Кузнецов, Вы писали:
ПК>Интересно, что, в свое время, предлагалось сделать аналогичное для метода push_back контейнеров, так, чтобы push_back мог бы не копировать созданный вовне объект, а конструировать его на месте по переданному шаблонному аргументу.
Так что же сталось с этим предложением? Это же на самом деле довольно важно, особенно если (о, ужас!) предположить, что у меня есть remote_allocator, конструирующий объекты на другой машине
Здравствуйте dupamid, Вы писали:
ПК>>решить эту проблему можно, закрыто унаследовав контейнер от распределителя. STLport решает это более сложным способом, но во время написания того кода оптимизация пустых баз еще не была внесена в черновик стандарта.
D>А как ее решает STLPort?
Ой, давно было, уже не помню точно, там что-то около сотни-другой строк, но Фомичев сам говорил, что, если бы в то время EBO уже была, этого бы не делали. Может, в новой версии даже переделали — не смотрел.
D>Наследоваться не всегда хороший подход. Например, при этом потребуется метод swap у алокатора, чтобы поддержать swap у контейнера.
Не понял... Чем эти два примера отличаются в отношении swap:
class Allocator { };
// 1class Container1 : private Allocator
{
public:
void swap(Container1& other)
{
// что здесь надо делать со static_cast<Allocator&>(*this),
// чего не надо делать во втором варианте с m_allocator?
}
};
// 2class Container2
{
public:
void swap(Container2& other)
{
// что здесь можно делать с m_allocator, чего нельзя сделать
// в первом варианте с static_cast<Allocator&>(*this)?
}
private:
Allocator m_allocator;
};
<< J 1.0 alpha 5 >>
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Здравствуйте orangy, Вы писали:
O>вопрос, который собственно меня больше всего интересует, это идентификация потенциальных проблем и затыков в том, что предлагается стандартом. Поэтому я и затеял эту тему. Я хочу понять, что
Фактически, ты сам верно перечислил основные проблемы, связанные с переопределением распределителей.
O>и, главное, почему было сделано при стандартизации библиотеки, на какие копромиссы пришлось пойти и ради чего.
В данном случае, основная причина, на мой взгляд, заключается в том, что средство, предназначавшееся в качестве "костыля" для решения одной проблемы (которую, к слову, это средство толком решать не в состоянии), начали снабжать дополнительными костылями под давлением все затягивавшихся сроков стандартизации. Как я понимаю, в данном случае основной принцип, которым пришлось руководствоваться заключается в том, что лучше не идельный стандарт, но вовремя, чем более идеальный, но поздно, или, вовсе, идеальный, но никогда. Таким образом, имхо, в данном случае, главные компромиссы носят скорее политический, нежели технический характер.
<< J 1.0 alpha 5 >>
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Здравствуйте Павел Кузнецов, Вы писали:
D>>А как ее решает STLPort?
ПК>Ой, давно было, уже не помню точно, там что-то около сотни-другой строк, но Фомичев сам говорил, что, если бы в то время EBO уже была, этого бы не делали. Может, в новой версии даже переделали — не смотрел.
Если вспомнишь, будет интересно посмотреть как это делалось, я смотрел новые версии там ничего особенного на эту тему я не увидел, может плохо смотрел...
D>>Наследоваться не всегда хороший подход. Например, при этом потребуется метод swap у алокатора, чтобы поддержать swap у контейнера.
ПК>Не понял... Чем эти два примера отличаются в отношении swap:
Сам не понял, что я имел ввиду... как говориться "краткость — сестра неясности", вспомню — напишу.
Здравствуйте Павел Кузнецов, Вы писали:
ПК>Фактически, ты сам верно перечислил основные проблемы, связанные с переопределением распределителей.
Вобщем понятно, компилятор в зубы и пытаться изобрести еще парочку велосипедов
Спасибо большое за дискуссию, было очень интересно Вылезаю из Януса и иду ставить оценки.