хорошо известно, что std::vector<bool>
не удовлетворяет требованиям Стандартного контейнера, главным образом потому, что упакованное представление предотвращает возврат T* x = &v[i]
указателя к bool.
Мой вопрос: может ли это быть исправлено/смягчено, когда reference_proxy перегружает адрес operator&
, чтобы вернуть указатель_proxy?
Прокси-указатель-указатель может содержать те же данные, что и reference_proxy в большинстве реализаций, а именно указатель на упакованные данные и маску, чтобы изолировать конкретный бит внутри указанного блока. В противном случае указатель pointer_proxy предоставит reference_proxy. По сути, оба прокси-сервера являются "жирными" указателями, которые, однако, по-прежнему довольно легки по сравнению с контейнерами-прокси на диске.
Вместо T* x = &v[0]
можно было бы сделать auto x = &v[0]
и без проблем использовать x
как if(*x)
. Я также хотел бы написать for(auto b: v) { /* ... */ }
Вопросы: будет ли такой многопроцессорный подход работать с алгоритмами STL? Или некоторые алгоритмы действительно полагаются на требование, чтобы x
должен был быть реальным bool*
? Или требуется слишком много последовательных пользовательских преобразований, которые мешают этому работать? Я хотел бы знать любые препятствия, прежде чем пытаться полностью выполнить приведенный выше эскиз реализации.
UPDATE (на основе ответа @HowardHinnant и этого древнего обсуждения на comp.std.С++)
Вы можете пройти долгий путь, чтобы почти имитировать встроенные типы: для любого заданного типа T пара прокси (например, reference_proxy и iterator_proxy) может быть сделана взаимосогласованной в том смысле, что reference_proxy:: operator &() и iterator_proxy:: operator *() взаимно противоположны.
Однако в какой-то момент нужно сопоставить объекты-прокси, чтобы они велись так, как T * или T &. Для прокси-серверов итераторов можно перегрузить оператор → () и получить доступ к интерфейсу шаблона T без переопределения всех функций. Однако для ссылочных прокси-серверов вам нужно будет перегрузить operator.(), И это не разрешено в текущем С++ (хотя Sebastian Redl представил такое предложение на BoostCon 2013). Вы можете сделать многословную работу как элемент .get() внутри ссылочного прокси или реализовать весь интерфейс T внутри ссылки (это то, что делается для vector:: bit_reference), но это либо потеряет встроенный синтаксис или ввести пользовательские преобразования, которые не имеют встроенной семантики для преобразований типов (вы можете иметь не более одного определяемого пользователем преобразования для каждого аргумента).