Может ли C ++ распределитель быть окончательным? - PullRequest
5 голосов
/ 23 марта 2019

Страница cpreference для требования Allocator не говорит о том, что Allocator должен быть наследуемым, то есть не говорит о том, что Allocator не должно быть окончательным.

Однако во многих библиотеках распределитель наследуется в частном порядке, чтобы воспользоваться преимуществами пустой оптимизации базового класса для распределителей без сохранения состояния. Например:

template <typename T, typename A = std::allocator<T>>
class Dummy_vector :private A {
    // ...
    A get_alloc() const
    {
        return static_cast<A>(*this);
    }
    // ...
};

Если A является окончательным, эта реализация прерывается.

Может ли Allocator быть окончательным? Я что-то пропустил? Или такая реализация должна включать специальный код для окончательного Allocator s?

(Примечание: под «специальным кодом для окончательного Allocator s» я имею в виду что-то вроде этого:

template <
    typename T,
    typename A = std::allocator<T>,
    bool = std::is_final<A>
>
class Dummy_vector :private A {
    // version for nonfinal allocators
    // ...
    A get_alloc() const
    {
        return static_cast<A>(*this);
    }
    // ...
};

template <typename T, typename A>
class Dummy_vector<T, A, true> {
    // special version for final allocators
};

)

1 Ответ

2 голосов
/ 23 марта 2019

Это действительно проблема. См. Также Отчет о дефектах стандартной библиотеки C ++ 2112 . Стандарт не требует, чтобы тип распределителя мог быть получен из. Однако в стандарте также не указано, что реализация является производной от типа распределителя. Таким образом, консенсус, по-видимому, заключается в том, что это следует рассматривать как ошибку реализации за то, что она не проверила, может ли тип распределителя быть получен из…

...