Должен ли allocator :: get_deleter () быть константным?

Я пытаюсь предоставить get_deleter() для моего шаблона класса распределителя без блокировок (код: здесь). Удалитель - это что-то вроде

template <typename T>
struct deleter {
  allocator<T>& alloc;
  void operator()(T* p) const noexcept {
    p->~T();
    alloc.deallocate(p);
  }
};

Обратите внимание, что alloc не должно быть const, поскольку deallocate() не const, что соответствует std::allocator::deallocate() . Теперь я не уверен, должен ли мой allocator::get_deleter() быть const. Дилемма заключается в следующем:

1. Обоснование использования const: сам метод не изменяет *this и является потокобезопасным (также см. Означает ли const потокобезопасность в C ++ 11?).

2. Обоснование того, что const: метод возвращает deleter, который можно использовать для изменения *this. Также избегает const_cast(), что необходимо, если метод const.

Любое предложение или идея? Лично я за const.


person Lingxi    schedule 13.03.2018    source источник
comment
Я бы лично поддержал намерение и не пометил бы его как const, если бы пометить его как const, это означало бы, что я могу удалить объект const без предупреждения. Не похоже на то, что я хочу разрешить. Может предоставить и то, и другое?   -  person spectras    schedule 13.03.2018
comment
@spectras Но ведь вы ведь можете вызвать деструктор объекта const? Однако operator delete() не принимает указатель const. Какая дилемма :(   -  person Lingxi    schedule 13.03.2018
comment
Это явное исключение: «Деструктор может быть вызван для объекта const, volatile или const volatile. [...] константная и изменчивая семантика не применяются к разрушаемому объекту ». См. stackoverflow.com/a/2271055/3212865   -  person spectras    schedule 13.03.2018
comment
@spectras Тогда я думаю, что это исключение также должно применяться к освобождению, иначе память объектов const не может быть восстановлена. deleter делает только эти две вещи: уничтожает и освобождает.   -  person Lingxi    schedule 13.03.2018
comment
Я понимаю вашу точку зрения. Это правда, что можно удалить константный объект. И на самом деле ваш удалитель запускает деструктор, поэтому действительно может применяться тот же аргумент, который используется для обоснования исключения уничтожения.   -  person spectras    schedule 13.03.2018


Ответы (1)


Не const_cast<allocator &>(*this)

Вы не знаете, будет ли у кого-нибудь значение const allocator<...> и неопределенное поведение. Даже если вы этого не сделаете, вы лжете о том, насколько const это на самом деле.

allocator::get_deleter не может быть const без const_cast, поэтому не должно.

Посмотреть вживую

person Caleth    schedule 13.03.2018
comment
Это уже обсуждалось в вопросе как профи для неконстант. - person Lingxi; 13.03.2018
comment
Отредактировано, чтобы быть более конкретным. Тот факт, что const_cast существует, не означает, что вы должны его использовать - person Caleth; 13.03.2018