Почему std::vector::get_allocator() возвращает по значению?

К моему удивлению, я получил ошибку при попытке использовать std::vector::get_allocator() с не копируемым распределителем. Почему std::vector::get_allocator() вернуть по значению, а не по ссылке?

template<typename T>
class nc_allocator {
public:
    using value_type = T;

    nc_allocator(nc_allocator const&) = delete;
    nc_allocator& operator=(nc_allocator const&) = delete;

    // Other required members.
};

std::vector<int, nc_allocator<int>> v;
// boom: use of deleted function
//           'nc_allocator<T>::nc_allocator(const nc_allocator<T>&) [with T = int]'
v.get_allocator();

2 ответа

Я получил ошибку при попытке использовать std::vector::get_allocator() с не копируемым распределителем.

Стандарт запрещает вам это делать. Требования к распределителю в 17.6.3.5 утверждают, что распределитель должен быть копируемым.

X a1(a);         Shall not exit via an exception.
                 post: a1 == a
X a1(move(a));   Shall not exit via an exception.
                 post: a1 equals the prior value
                 of a.

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

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

Стандарт просто диктует так:

[C++11: 23.2.1/7]: [..] Во всех типах контейнеров, определенных в этом разделе, член get_allocator() возвращает копию распределителя, использованного для создания контейнера, или, если этот распределитель был заменен, копию самой последней замены [..]

Я подозреваю, что @ Вон прав в своей гипотезе, что распределители предназначены для использования в качестве "ручек".

По очень свободной аналогии, вы когда-нибудь могли бы написать не копируемый функтор для использования со стандартными алгоритмами?

Другие вопросы по тегам