Требования к стандартным типам указателей распределителя библиотек - PullRequest
8 голосов
/ 25 марта 2011

Я пытаюсь написать класс разреженных матриц дерева.Короче говоря, quadtree_matrix<T> - это либо нулевая матрица, либо четверка (ne, nw, se, sw) из quadtree_matrix<T>.

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

Мне нужно будет выделить два разных типа данных: либо T, либо node, который содержит четыре указателя (либо на T, либо на узел).Для всех алгоритмов, которые я рассмотрю, я точно знаю, какие данные ожидать, потому что я знаю, каковы размеры подматриц, с которыми я сталкиваюсь в любой точке алгоритма (мне даже не нужно хранить эти размеры).

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

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

Если бы указатели типа распределителя были указателями разновидностей сада, у меня не было бы никаких проблем: по крайней мере, я мог бы использовать указатели, чтобы аннулировать и повторно интерпретировать их в нужный тип (либо node*, либо T*),Я мог бы также использовать объединение (возможно, лучше).

Насколько я знаю, нет требования к PODness типов allocator::pointer.Они должны быть только итераторами с произвольным доступом.

Теперь мой вопрос:

Учитывая шаблон класса распределителя A<T> (или его эквивалент A::rebind<T>::other), есть лилюбая гарантия на:

  1. Способность к статическому приведению A<T>::pointer к A<U>::pointer при условии U является доступной базой T?
  2. Способность к статическому приведению A<T>::pointer к A<U>::pointer при условии T является доступной базой U, а "тип времени выполнения" (что бы это ни значило в данном контексте) заинтересованного лица - U?
  3. Тип A<void>::pointer (если это имеет смысл)?

Или есть решение моей проблемы?думать о?

Ответы [ 3 ]

2 голосов
/ 25 марта 2011

Из таблиц в 20.1.5 / 2 ясно видно, что тип A<T>::pointer должен быть «указатель на T».Так как эти типы указателей обычно конвертируемы, ваши 1 и 2 верны.Из этого следует, что A<void>::pointer должно быть void*.

РЕДАКТИРОВАТЬ: Есть также явная формулировка в 20.1.5 / 4 (это относится к тому, что стандартные контейнеры могут предполагать о распределителях):

Указатель членов typedef, const_pointer, size_type и diff_type должен быть соответственно T *, T const *, size_t и ptrdiff_t.

0 голосов
/ 25 марта 2011

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

Поэтому я бы рекомендовал двухэтапный подход:

  • Напишите небольшой умный указатель, который использует данный распределитель для выполнения уничтожения (вместо delete)
  • Используйте boost::variant на своих указателях

Таким образом, у вас есть и автоматическое управление памятью и совместимость .

0 голосов
/ 25 марта 2011

Нет, не совсем.

Существует требование, чтобы A :: pointer конвертировался в A :: const_pointer и A :: void_pointer, но это все, что яможно найти.

A :: указатель, вероятно, будет void*, если только у вас нет какой-то необычной специальной памяти.

...