Концепция и реализация GCC std :: vector

Давайте попробуем создать совпадение типа указателя
оба RandomAccessIterator
и NullablePointer концепции.
Цель состоит в том, чтобы создать Распределитель
чтобы использовать std :: vector с нашим указателем типа. Вы можете найти фрагмент Вот

Проблема возникает при попытке скомпилировать этот код:

int main()
{
std::vector<float, allocator<float>> t {0.f, 0.f};
}

Мы получаем следующее сообщение об ошибке:

/usr/bin/../lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_vector.h:173:6: error:
value of type 'pointer' (aka 'ptr_like<int>') is not contextually convertible
to 'bool'
if (__p)

Здесь мы видим, что наш тип должен быть bool конвертируемым. Это не сложно сделать,
и если у людей есть экземпляр нашего типа указателя, они, скорее всего, будут использовать его в любом случае.
Итак, давайте сделаем это и раскомментируем следующее в нашем фрагменте:

// In detail::ptr_like we add :
operator bool() const;

И мы получаем следующую ошибку с Clang:

/usr/bin/../lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_vector.h:168:25: error:
conditional expression is ambiguous; 'pointer' (aka 'ptr_like<int>') can be
converted to 'int' and vice versa
{ return __n != 0 ? _M_impl.allocate(__n) : 0; }

Ошибка Кланга показывает нам, почему мы попадаем в неприятности.
Теперь единственные жизнеспособные решения, которые я нашел, следующие:

  • Замена 0 с ключевым словом c ++ 11 nullptr когда запрашивается c ++ 11
  • Замена 0 приведением к типу указателя static_cast<pointer>(0)
  • Обновление концепции требования для указателя в концепции Allocator.
  • Не используйте конструктор с std::initializer_list (печальный)

Неправильно ли определять пользовательские указатели в C ++?

Это ошибка?

3

Решение

Расширяю свой комментарий.

{ return __n != 0 ? _M_impl.allocate(__n) : 0; }

Первый результат можно преобразовать в bool в int, Второй результат можно преобразовать в int, Это такой же хороший результат, как и преобразование второго результата в pointerтак что это неоднозначно.

Но мы не хотим bool конверсия будет доступна здесь, поэтому мы можем сделать это explicit, Это все еще будет доступно в логических условиях и тому подобное, как я опишу Вот.
Быть контекстуально конвертируемым в bool это еще одно условие, которое Стандарт помещает в пользовательские типы указателей, удовлетворяющие NullablePointer требования (с 2011 года — см. 17.6.3.3/3).

4

Другие решения

Я предлагаю определить оператор преобразования как явный. Например

explicit operator bool() const;
2

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector