хорошо известно, что std::vector<bool>
не удовлетворяет требованиям стандарта к контейнерам, главным образом потому, что упакованное представление не позволяет T* x = &v[i]
от возврата указателя на логическое значение.
У меня такой вопрос: можно ли это исправить/смягчить, когда reference_proxy перегружает адрес operator&
для возврата pointer_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*
? Или требуется слишком много последовательных пользовательских преобразований, которые мешают этому работать? Я хотел бы узнать о любом из таких препятствий, прежде чем пытаться полностью завершить приведенный выше набросок реализации.
ОБНОВЛЕНИЕ (на основе ответа @HowardHinnant и этого древнее обсуждение comp.std.c++)
Вы можете пройти долгий путь, чтобы практически имитировать встроенные типы: для любого заданного типа T пара прокси (например, reference_proxy и iterator_proxy) может быть взаимно согласована в том смысле, что reference_proxy::operator&() и iterator_proxy::operator* () являются обратными друг другу.
Однако в какой-то момент нужно отобразить обратно прокси-объекты, чтобы они вели себя как T* или T&. Для прокси-итераторов можно перегрузить оператор->() и получить доступ к интерфейсу шаблона T без повторной реализации всей функциональности. Однако для эталонных прокси вам потребуется перегрузить оператор.(), а это не разрешено в текущем C++ (хотя Себастьян Редл представил такое предложение на BoostCon 2013). Вы можете сделать подробный обходной путь, например член .get() внутри ссылочного прокси, или реализовать весь интерфейс T внутри ссылки (это то, что делается для vector::bit_reference), но это либо потеряет встроенный синтаксис или введите пользовательские преобразования, которые не имеют встроенной семантики для преобразования типов (у вас может быть не более одного пользовательского преобразования для каждого аргумента).
reference_type
было lvalue of T, поэтому требований к контейнеру недостаточно. - person K-ballo   schedule 30.12.2012