это allocator_traits :: deallocate действительный уничтожитель shared_ptr - PullRequest
0 голосов
/ 31 октября 2018

Полагаю, этот вопрос действительно касается дизайна std::allocator_traits и предоставления пользовательского распределителя. Если я хочу создать std::shared_ptr<>, используя собственный распределитель, могу ли я использовать std :: allocator_traits?

В принципе, это правильно?

WidgetAllocator allocator;
std::shared_ptr<Widget> widget(allocator.allocate(), std::allocator_traits<WidgetAllocator>::deallocate);

1 Ответ

0 голосов
/ 31 октября 2018

В принципе, это правильно?

std::shared_ptr<Widget> widget(allocator.allocate(), std::allocator_traits<WidgetAllocator>::deallocate);

Это не правильно.

Во-первых, распределителю не гарантируется наличие нулевой функции-члена allocate.

Хорошо, давайте предположим, что WidgetAllocator обеспечивает такую ​​перегрузку, хотя это не совсем типично для распределителя. Но что более важно, std::allocator_traits::deallocate не вызывается с Widget*. Список аргументов ( Alloc& a, pointer p, size_type n ).

Так, каково рекомендуемое использование allocator_traits?

Вам следует использовать std::allocator_traits всякий раз, когда вы хотите использовать одну из необязательных функций распределителя, таких как Alloc::is_always_equal, и распределитель, который вы хотите использовать, не предоставляет дополнительную функцию, или распределитель является аргументом шаблона, и вы хотите поддерживать все распределители независимо от того, предоставляют ли они дополнительные функции.

std::allocator_traits обеспечивает реализацию по умолчанию для дополнительных функций распределителя.

Должен ли я вызывать методы для распределителя напрямую?

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

...